Java Jar ClassNotFoundException 即使依赖库存在
Java Jar ClassNotFoundException even though dependent library exists
我正在创建一个使用(非官方)Discord API、JDA 的 (Minecraft) Forge mod。我在 Eclipse IDE.
中这样做
在 IDE 中,我可以很好地添加具有依赖项的 JDA,并且在我的代码中没有错误。然后,使用 gradlew 并编译它,当我尝试 运行 它(在 Minecraft 中)时出现错误。
我让一些人检查了我的 build.gradle 以确保它是正确的,它是正确的。我现在假设这是一个一般的 Java 错误。
无论如何,错误:
java.lang.NoClassDefFoundError: org/apache/http/nio/reactor/IOReactorException
at com.mashape.unirest.http.HttpClientHelper.prepareRequest(HttpClientHelper.java:151)
at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:131)
at com.mashape.unirest.request.BaseRequest.asString(BaseRequest.java:56)
at net.dv8tion.jda.requests.Requester.toObject(Requester.java:100)
at net.dv8tion.jda.requests.Requester.post(Requester.java:55)
at net.dv8tion.jda.entities.impl.JDAImpl.login(JDAImpl.java:152)
at net.dv8tion.jda.JDABuilder.buildAsync(JDABuilder.java:272)
at net.dv8tion.jda.JDABuilder.buildBlocking(JDABuilder.java:307)
at com.scarabcoder.ereijan.gui.GuiLogin.connect(GuiLogin.java:168)
at com.scarabcoder.ereijan.gui.GuiLogin.func_146284_a(GuiLogin.java:143)
at net.minecraft.client.gui.GuiScreen.func_73864_a(GuiScreen.java:466)
at com.scarabcoder.ereijan.gui.GuiLogin.func_73864_a(GuiLogin.java:128)
at net.minecraft.client.gui.GuiScreen.func_146274_d(GuiScreen.java:554)
at net.minecraft.client.gui.GuiScreen.func_146269_k(GuiScreen.java:523)
at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:1674)
at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1024)
at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:349)
at net.minecraft.client.main.Main.main(SourceFile:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.multimc.onesix.OneSixLauncher.launchWithMainClass(OneSixLauncher.java:310)
at org.multimc.onesix.OneSixLauncher.launch(OneSixLauncher.java:395)
at org.multimc.EntryPoint.listen(EntryPoint.java:170)
at org.multimc.EntryPoint.main(EntryPoint.java:54)
Caused by: java.lang.ClassNotFoundException: org.apache.http.nio.reactor.IOReactorException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:106)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 32 more
在 jar 文件中:
有什么帮助吗??
NoClassDefFoundError - 是由于您的代码所依赖的 class 文件在编译时存在但在运行时未找到。检查您的构建和运行时 classpaths.
将 Discord API 的依赖项添加到您的项目应该可以解决问题。为您的 API 使用 shaided Jar 也可能有效。
在这种情况下,问题实际上出在 MinecraftForge 上,不一定是由于错误,而是实际上是由于 Forge 实施的保护。
Forge 可以完全控制加载 mod 的 classes 并且它专门检查每个 class 的包信息,它根据一组受限的包路径加载以保护它自己的依赖项不会因加载相似依赖项的不同版本而意外被覆盖。在这种情况下,Forge 使用了一些 Apache 库,因此它阻止了从 org.apache
包命名空间加载 classes。
因此,在加载 mod 的 class 时,Forge 注意到这些 class 来自 org.apache
并选择不加载它们。这意味着当 JDA
使用的 Unirest
依赖项尝试使用它所依赖的 Apache 依赖项时,它们不存在,并且您遇到 NoClassDefFoundError
.
处理这个问题的最好方法是正确隐藏你的依赖项。考虑到您正在使用 Forge,您很可能正在使用 Gradle。 MinecraftForge 实际上有一个关于如何正确隐藏依赖项的指南 here。
我正在创建一个使用(非官方)Discord API、JDA 的 (Minecraft) Forge mod。我在 Eclipse IDE.
中这样做在 IDE 中,我可以很好地添加具有依赖项的 JDA,并且在我的代码中没有错误。然后,使用 gradlew 并编译它,当我尝试 运行 它(在 Minecraft 中)时出现错误。
我让一些人检查了我的 build.gradle 以确保它是正确的,它是正确的。我现在假设这是一个一般的 Java 错误。
无论如何,错误:
java.lang.NoClassDefFoundError: org/apache/http/nio/reactor/IOReactorException
at com.mashape.unirest.http.HttpClientHelper.prepareRequest(HttpClientHelper.java:151)
at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:131)
at com.mashape.unirest.request.BaseRequest.asString(BaseRequest.java:56)
at net.dv8tion.jda.requests.Requester.toObject(Requester.java:100)
at net.dv8tion.jda.requests.Requester.post(Requester.java:55)
at net.dv8tion.jda.entities.impl.JDAImpl.login(JDAImpl.java:152)
at net.dv8tion.jda.JDABuilder.buildAsync(JDABuilder.java:272)
at net.dv8tion.jda.JDABuilder.buildBlocking(JDABuilder.java:307)
at com.scarabcoder.ereijan.gui.GuiLogin.connect(GuiLogin.java:168)
at com.scarabcoder.ereijan.gui.GuiLogin.func_146284_a(GuiLogin.java:143)
at net.minecraft.client.gui.GuiScreen.func_73864_a(GuiScreen.java:466)
at com.scarabcoder.ereijan.gui.GuiLogin.func_73864_a(GuiLogin.java:128)
at net.minecraft.client.gui.GuiScreen.func_146274_d(GuiScreen.java:554)
at net.minecraft.client.gui.GuiScreen.func_146269_k(GuiScreen.java:523)
at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:1674)
at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1024)
at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:349)
at net.minecraft.client.main.Main.main(SourceFile:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.multimc.onesix.OneSixLauncher.launchWithMainClass(OneSixLauncher.java:310)
at org.multimc.onesix.OneSixLauncher.launch(OneSixLauncher.java:395)
at org.multimc.EntryPoint.listen(EntryPoint.java:170)
at org.multimc.EntryPoint.main(EntryPoint.java:54)
Caused by: java.lang.ClassNotFoundException: org.apache.http.nio.reactor.IOReactorException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:106)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 32 more
在 jar 文件中:
有什么帮助吗??
NoClassDefFoundError - 是由于您的代码所依赖的 class 文件在编译时存在但在运行时未找到。检查您的构建和运行时 classpaths.
将 Discord API 的依赖项添加到您的项目应该可以解决问题。为您的 API 使用 shaided Jar 也可能有效。
在这种情况下,问题实际上出在 MinecraftForge 上,不一定是由于错误,而是实际上是由于 Forge 实施的保护。
Forge 可以完全控制加载 mod 的 classes 并且它专门检查每个 class 的包信息,它根据一组受限的包路径加载以保护它自己的依赖项不会因加载相似依赖项的不同版本而意外被覆盖。在这种情况下,Forge 使用了一些 Apache 库,因此它阻止了从 org.apache
包命名空间加载 classes。
因此,在加载 mod 的 class 时,Forge 注意到这些 class 来自 org.apache
并选择不加载它们。这意味着当 JDA
使用的 Unirest
依赖项尝试使用它所依赖的 Apache 依赖项时,它们不存在,并且您遇到 NoClassDefFoundError
.
处理这个问题的最好方法是正确隐藏你的依赖项。考虑到您正在使用 Forge,您很可能正在使用 Gradle。 MinecraftForge 实际上有一个关于如何正确隐藏依赖项的指南 here。