JavaAssist CtClass работает, но выдает NoClassDefError при вызове конструктора - PullRequest
0 голосов
/ 01 марта 2020

Когда я не вызываю конструктор параметра с отражением, он выдает NoClassDefError. Я уверен, что Bukkit загрузил все классы моего проекта, потому что он не выдает исключение, когда класс вызывается с Class.forName (String) .

Как я могу разрешить ClassNotFound с этим кодом?

Я использовал этот код:

  ClassPool pool = ClassPool.getDefault();

        pool.insertClassPath(new ClassClassPath(ReflectedNBTCompound.class));
        CtClass cl = pool.getCtClass(ReflectedNBTWrapper.class.getCanonicalName());
        CtClass ct = pool.makeClass("NBTCompatibleTileEntity", ctClass);
        ct.addField(new CtField(cl, "nbtField", ct));
        ct.addConstructor(CtNewConstructor.make(
                "public NBTCompatibleTileEntity(){" +
                        " this.nbtField = new skywolf46.NBTUtil.v1_3.NBTData.ReflectedNBTCompound();" +
                        "System.out.println(\"Object created!\");" +
                        "}"

                , ct
        ));
        ct.addMethod(CtMethod.make(
                "public skywolf46.NBTUtil.v1_3.NBTData.ReflectedNBTCompound getNBT(){" +
                        "  return nbtField;" +
                        "}"
                , ct));

        ct.addMethod(CtMethod.make(
                "public void load(" + BukkitVersionUtil.getNMSClass("NBTTagCompound").getName() + " comp){" +
                        "  if(comp.hasKey(\"ReflectedNBT\"))" +
                        "    nbtField = new skywolf46.NBTUtil.v1_3.NBTData.ReflectedNBTCompound(comp.getCompound(\"ReflectedNBT\"));" +
                        "}"
                , ct));
        Class c = ct.toClass();
        c.getConstructor().newInstance();
        Bukkit.getConsoleSender().sendMessage("§5ReflectedNBTWrapper §7| §aInitialized! ");

Ошибка:

java.lang.NoClassDefFoundError: skywolf46/NBTUtil/v1_3/NBTData/ReflectedNBTCompound
        at java.lang.Class.getDeclaredConstructors0(Native Method) ~[?:1.8.0_202]
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) ~[?:1.8.0_202]
        at java.lang.Class.getConstructor0(Class.java:3075) ~[?:1.8.0_202]
        at java.lang.Class.getConstructor(Class.java:1825) ~[?:1.8.0_202]
        at skywolf46.NBTUtil.v1_3.ReflectedNBTWrapper.initBukkit(ReflectedNBTWrapper.java:88) ~[?:?]
        at skywolf46.NBTUtil.v1_3.ReflectedNBTWrapper.onEnable(ReflectedNBTWrapper.java:27) ~[?:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:337) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:403) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugin(CraftServer.java:381) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugins(CraftServer.java:330) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.t(MinecraftServer.java:422) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.l(MinecraftServer.java:383) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.a(MinecraftServer.java:338) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.DedicatedServer.init(DedicatedServer.java:272) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:545) [spigot-ram-patched.jar:git-Spigot-79a30d7-acbc348]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]
Caused by: java.lang.ClassNotFoundException: skywolf46.NBTUtil.v1_3.NBTData.ReflectedNBTCompound
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_202]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_202]
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[?:1.8.0_202]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_202]

1 Ответ

2 голосов
/ 01 марта 2020

Вы, вероятно, определяете этот класс в неправильном загрузчике классов, в bukkit каждый плагин находится в отдельном загрузчике классов, а .toClass() использует загрузчик классов контекста Thread, который, вероятно, установлен на другой загрузчик классов.
Так что, когда ваш новый Класс загружается, он пытается найти другие классы из вашего плагина, но не может, потому что они не доступны из этого загрузчика классов.

Попробуйте использовать

Class c = ct.toClass(ReflectedNBTCompound.class)

или

Class c = ct.toClass(MyPlugin.class.getClassLoader())
...