Javassist CtClass 可以工作,但在调用构造函数时抛出 NoClassDefError

标签 java reflection bukkit javassist

当我通过反射调用无参数构造函数时,它会抛出 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]

最佳答案

您可能在错误的类加载器中定义了此类,在 bukkit 中,每个插件都位于单独的类加载器中,并且 .toClass() 使用线程上下文类加载器,该类加载器可能设置为某个不同的类加载器.
因此,当加载新类时,它会尝试从插件中查找其他类,但会失败,因为无法从此类加载器访问它们。

尝试使用

Class c = ct.toClass(ReflectedNBTCompound.class)

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

关于Javassist CtClass 可以工作,但在调用构造函数时抛出 NoClassDefError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60472956/

相关文章:

java - 我可以在类外用 Java 定义一个函数吗

java - Java中使用数组反转数字

应用程序的Java控制台和GUI模式?

c# - 动态执行委托(delegate)

java - 怎样才能让鸡蛋不会对队友造成击退?

java - 如何设置 block 数据值?

java - MappedByteBuffer 内存使用

java - 在 Windows 7 上运行 Android Studio 失败,找不到 Android SDK

ruby - 获取当前正在执行的方法的名称

java - 是什么原因导致 "object is not an instance of declaring class"?