英文:
ClassNotFoundException after loading the classfile
问题
我尝试使用URLClassloader加载jar文件中的类。但我遇到了一个问题:如果我从加载的类创建一个新实例,我会得到一个ClassNotFoundException,我不知道错误在哪里。以下是我加载类的代码部分:
private void loadClasses() throws IOException, ClassNotFoundException {
JarFile[] jarFile = {
new JarFile("lib/core-api-bukkit-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-api-common-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-plugin-common-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-db-common-0.0.1-SNAPSHOT.jar")
};
for (JarFile currentFile : jarFile) {
try {
System.out.println("当前文件:" + currentFile.getName());
Enumeration<JarEntry> e = currentFile.entries();
URL[] urls = { new URL("jar:file:" + currentFile.getName() + "!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls, getClassLoader());
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class")) {
continue;
}
String className = je.getName().substring(0, je.getName().length() - 6);
className = className.replace('/', '.');
Class<?> c = cl.loadClass(className);
System.out.println("加载类:" + c.getName());
}
} finally {
currentFile.close();
}
}
}
以下是控制台输出:
java.lang.NoClassDefFoundError: at/cybercraft/core/plugin/common/player/Player
at at.cybercraft.core.plugin.bukkit.BukkitCorePlugin.registerClasses(BukkitCorePlugin.java:28) ~[?:?]
at at.cybercraft.core.plugin.bukkit.BukkitCorePlugin.onEnable(BukkitCorePlugin.java:22) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
...
Caused by: java.lang.ClassNotFoundException: at.cybercraft.core.plugin.common.player.Player
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_242]
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:101) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
...
诚挚的问候,
Daniel
英文:
I tried to load classes of a jar-file by using URLClassloader.
But I have one problem: If I create a new instance from a class I loaded, I am getting a ClassNotFoundException and I don't know where the mistake is.
Here is my code to load the classes:
private void loadClasses() throws IOException, ClassNotFoundException {
JarFile[] jarFile = {
new JarFile("lib/core-api-bukkit-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-api-common-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-plugin-common-0.0.1-SNAPSHOT.jar"),
new JarFile("lib/core-db-common-0.0.1-SNAPSHOT.jar")
};
for (JarFile currentFile : jarFile) {
try {
System.out.println("Current File: " + currentFile.getName());
Enumeration<JarEntry> e = currentFile.entries();
URL[] urls = { new URL("jar:file:" + currentFile.getName() + "!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls, getClassLoader());
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class")) {
continue;
}
String className = je.getName().substring(0,je.getName().length() - 6);
className = className.replace('/', '.');
Class<?> c = cl.loadClass(className);
System.out.println("Load class " + c.getName());
}
} finally {
currentFile.close();
}
}
}
Here is the console output:
java.lang.NoClassDefFoundError: at/cybercraft/core/plugin/common/player/Player
at at.cybercraft.core.plugin.bukkit.BukkitCorePlugin.registerClasses(BukkitCorePlugin.java:28) ~[?:?]
at at.cybercraft.core.plugin.bukkit.BukkitCorePlugin.onEnable(BukkitCorePlugin.java:22) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:357) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:317) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.reload(CraftServer.java:741) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.Bukkit.reload(Bukkit.java:535) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-db6de12-18fbb24]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_242]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_242]
at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot.jar:git-Spigot-db6de12-18fbb24]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_242]
Caused by: java.lang.ClassNotFoundException: at.cybercraft.core.plugin.common.player.Player
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_242]
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:101) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:86) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
at java.lang.ClassLoader.loadClass(ClassLoader.java:419) ~[?:1.8.0_242]
at java.lang.ClassLoader.loadClass(ClassLoader.java:352) ~[?:1.8.0_242]
... 25 more
Yours sincerely
Daniel
答案1
得分: 0
收到错误消息 Error occurred while enabling BukkitCorePlugin
以及堆栈跟踪中的 NoClassDefFoundError
。
看起来像是您的代码加载了一个类,当它被初始化时,由于无法通过相应的类加载器加载所需的类,导致初始化失败。
这可能是因为您为每个 JAR 文件创建了一个新的 ClassLoader
实例,并且这些类加载器彼此之间没有依赖关系。
通常情况下,当类加载器无法自己找到一个类时,它会委托给其父类加载器(实际上,它首先询问父类加载器,只有在父类加载器无法提供所请求的类时,它才自行查找)。您的类加载器只有一个共同的父类加载器,但彼此之间没有关联。因此,当位于 lib/core-api-common-0.0.1-SNAPSHOT.jar
中的类引用位于 lib/core-api-bukkit-0.0.1-SNAPSHOT.jar
中的类时,尽管已加载,但可能无法找到该类。
英文:
You get the message Error occurred while enabling BukkitCorePlugin
in the stack trace, together with a NoClassDefFoundError
.
That looks like that your code loads a class and when it is initialised, that fails because a required class cannot be loaded by the respective class loader.
That could be because you create a new instance of ClassLoader
for each jar, and those classloader do not depend from each other.
Usually, when a classloader cannot find a class itself, it delegates to its parent (in fact, it asks the parent first, and only when the parent does not come up with the requested class, it looks itself). Your classloaders do have only a common parent, but are not related to each other. So when a class from lib/core-api-common-0.0.1-SNAPSHOT.jar
refers to a class that is located in lib/core-api-bukkit-0.0.1-SNAPSHOT.jar
, that could not be found, although it is already loaded.
专注分享java语言的经验与见解,让所有开发者获益!
评论