Search code examples
javalinuxmacosmavenclassnotfoundexception

NoClassDefFoundError when running application on linux (but not on mac)


I've created an application for automatically downloading weather data and adding these data for specific location to a database. This application works as intended within IntelliJ

Now I want to run this application as a stand-alone application. I, therefore, created a jar using maven. The jar is a "lean" jar without all dependencies. The dependencies are output to a directory lib. The maven plugins are configured as:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>nl.wur.fbr.data.weather.WeatherData</mainClass>
                    </manifest>
                </archive>
                <outputDirectory>${project.build.directory}/WeatherData</outputDirectory>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <phase>install</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/WeatherData/lib</outputDirectory>
                        <overWriteReleases>true</overWriteReleases>
                        <overWriteSnapshots>true</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>

The classpath is added to the manifest (I've checked) and all dependencies are output to the lib directory.

When I run this application on my Mac (Java version 1.8.0), everything works fine. But when I run it on a linux server (after zipping and unzipping and also running Java 1.8.0), I get the following error:

$ java -jar weatherData-1.0-SNAPSHOT.jar 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: nl/wur/fbr/om/factory/InstanceFactory
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: nl.wur.fbr.om.factory.InstanceFactory
    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)
    ... 7 more

Typically a classpath problem, but why would it behave differently on macosx and on linux? Both the main jar file (with the manifest containing the classpath) and the lib directory are the same.


Solution

  • I am not sure what is exactly causing this issue but below steps might help to narrow down the path. 
    
    Step 1 : Verify the class file nl.wur.fbr.om.factory.InstanceFactory  present inside jar
    
    Step 2: Verify MANIFEST.MF file and check for the following entries -
    ex: Main-Class: nl.wur.fbr.data.weather.WeatherData
    Class-Path: 
      ../config/
      classes12.jar
      bc4jct.jar
      bc4jdomorcl.jar
      bc4jmt.jar
      commons-beanutils-bean-collections.jar
      commons-beanutils-core.jar
    
     Step 3 : Verify the jar entry is present in Class-Path
    
     Step 4:  If the issue still persists, try running with java -classpath option.