Skip to content
Advertisement

Java Jar ClassNotFoundException even though dependent library exists

I am creating a (Minecraft) Forge mod that uses the (unofficial) Discord API, JDA. I am doing this in the Eclipse IDE.

In the IDE, I can add the JDA with dependencies just fine and get no errors in my code. Then, using gradlew and compiling it, I get an error when I try running it (in Minecraft).

I had a few people check my build.gradle to make sure it was correct, and it is. I’m assuming at this point that it is a general Java error.

Anyways, the error:

    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

And inside the jar file: The path to the "missing" class (it exists)

Any help??

Answer

In this case, the problem actually lies with MinecraftForge, not necessarily due to a bug but actually due to a protection that Forge implemented.

Forge has full control over loading the classes of a mod and it specifically checks the package information of every class it loads against a set of restricted package paths to protect its own dependencies from accidentally being overwritten by loading a different version of a similar dependency. In this case, Forge uses a few Apache libs, so it prevents the loading of classes from the org.apache package namespace.

Thus, when loading the classes of your mod, Forge notices that these classes come from org.apache and chooses to specifically not load them. This means that when the Unirest dependency used by JDA attempts to use the Apache dependencies it relies on, they don’t exist, and you encounter the NoClassDefFoundError.

The best way to deal with this is to properly shade your dependencies. Considering you’re using Forge, you are most likely using Gradle. MinecraftForge actually has a guide on how to properly shade your dependencies here.

Advertisement