When I invoke no parameter constructor with reflection, it throws NoClassDefError. I'm sure bukkit loaded all of my project's class, cause It not throws exception when class called with Class.forName(String).
How can I can resolve ClassNotFound with this code?
I used this code :
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! ");
Error:
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]
You are probably defining this class in wrong class loader, in bukkit each plugin is in separate class loader, and .toClass()
use Thread context class loader that is probably set to some different class loader.
So when your new class is loaded it tries to find that other classes from your plugin but fails because they are not accessible from this class loader.
Try to use
Class c = ct.toClass(ReflectedNBTCompound.class)
or
Class c = ct.toClass(MyPlugin.class.getClassLoader())