czchlong
czchlong

Reputation: 2594

Dependency is present in MANIFEST.MF, but still get NoClassDefFoundError

I used the maven-assembly-plugin to put all my dependencies into a lib folder - I can confirm that the required dependency jar is inside the lib folder.

I am using maven-jar-plugin with the following snippet to link with the dependencies in the lib folder:

<configuration>
    <archive>
        <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>my.main.class.MainClass</mainClass>
        </manifest>
    </archive>
</configuration>

I used jd-gui.exe to decompile my jar and I can see that the MANIFEST.MF file contains my dependency as lib/MyLibFile.jar.

However, when I try to run my app in a Linux environment like so:

java -cp MyApp.jar my.class.app.MainClass ...

I get NoClassDefFoundError. However, if I do the following:

java -cp MyApp.jar:lib/* my.class.app.MainClass ...

The app runs.

Could someone please point why MyApp.jar cannot read the dependent library file during runtime?

Update:

Tried with java -jar MyApp.jar and this is also not working. I believe something is wrong with my MANIFEST.MF but I cannot find the issue.

EDIT:

The following is my simplified MANIFEST.MF -

Manifest-Version: 1.0
Built-By: dev
Build-Jdk: 1.7.0_25
Class-Path: lib/LibA.jar lib/LibB.jar lib/MyLibFile.jar
Created-By: Apache Maven
Main-Class: my.main.class.MainClass
Archiver-Version: Plexus Archiver

Project directory structure:

 lib/
 config/
 MyApp.jar

Content of lib directory:

LibA.jar
LibB.jar
MyLibFile.jar

My dependency is in the MyLibFile.jar.

I run my app by first cd into my project directory, then from there I execute java -jar MyApp.jar

This is the stacktrace:

Exception in thread "main" java.lang.NoClassDefFoundError: dependency/lib/path/ClassName
        at my.class.path.MyApp.main(MyApp.java:65)
Caused by: java.lang.ClassNotFoundException: dependency.lib.path.ClassName
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

Upvotes: 0

Views: 1100

Answers (1)

JB Nizet
JB Nizet

Reputation: 692023

java -cp MyApp.jar my.class.app.MainClass

The above command doesn't care about the manifest of the jar file. It explicitely sets the classpath to MyApp.jar only, and asks to run the class my.class.app.MainClass instead of the main class set in the manifest.

To execute an executable jar file (i.e. the main class setin the manifest, with all the dependencies listed in the manifest in the classpath), you must use the -jar option instead of the -cp option:

java -jar MyApp.jar

Upvotes: 1

Related Questions