Maven: NoClassDefFoundError in the main thread
Asked Answered
D

2

26

I am currently building a little Apache-Mina Server app. I am using Maven to build it. When i try to run the jar, I get the following error:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/mina/filter/codec/ProtocolCodecFactory 
Caused by: java.lang.ClassNotFoundException: org.apache.mina.filter.codec.Protoc  olCodecFactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: de.fr1zle.gpsserver.GpsServer. Program will exit.

Running in eclipse is not a problem.

This is what the generated MANIFEST looks like:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: fr1zle
Build-Jdk: 1.6.0_23
Main-Class: de.fr1zle.gpsserver.GpsServer
Class-Path: commons-lang-2.1.jar plexus-utils-1.1.jar junit-4.8.2.jar 
 log4j-1.2.14.jar slf4j-jdk14-1.5.11.jar slf4j-api-1.5.11.jar antlr-2.
 7.6.jar commons-collections-3.1.jar dom4j-1.6.1.jar hibernate-commons
 -annotations-3.2.0.Final.jar hibernate-jpa-2.0-api-1.0.0.Final.jar jt
 a-1.1.jar hibernate-annotations-3.5.6-Final.jar hibernate-core-3.5.6-
 Final.jar mysql-connector-java-5.1.15.jar mina-core-2.0.3.jar

And this is (part of) my pom.xml:

<groupId>de.fr1zle.gpsserver</groupId>
    <artifactId>GPSServer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>GPSServer</name>
    <packaging>jar</packaging>
    <description>Tracks location of GPS modules and the information they submit.</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>de.fr1zle.gpsserver.GpsServer</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

What am I doing wrong here?

Diondione answered 26/4, 2011 at 23:57 Comment(0)
B
10

When you run from Eclipse, Eclipse configures the class path for you. Therefore, you don't run into this issue.

When you are running outside of Eclipse, you need to set up the CLASSPATH either by providing the path to these jar files ie file:/dev/libs/mina-core-2.0.3.jar in the MANIFEST.MF or by adding the -cp option when executing the app. Don't forget that the entries in the class-path in the manifest file are either relative to the JAR in which they are embedded or absolute path to a local file directory.

Your other option is to package it as one jar using the maven assembly plugin jar-with-dependencies.

Base answered 27/4, 2011 at 0:5 Comment(3)
Thank you very much :) This solved my problem! I used the jar-with dependencies.Diondione
much appreciated, that probably saved me hours of searchingThrove
@Throve - Glad to be of help! Happy mavenizing :)Base
S
24

Another option is to use maven-dependency-plugin. You can copy all dependent libraries to a folder such as lib, and use that for classpath.

In order to copy dependencies:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>
                    ${project.build.directory}/lib
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

and for the classpath, here classpathPrefix specifies that all dependencies should be located in a "lib" folder relative to the archive.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.citusdata.hadoop.HadoopTest</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

For further information:

http://www.ibm.com/developerworks/java/library/j-5things13/index.html http://maven.apache.org/plugins/maven-dependency-plugin/usage.html

Stickler answered 9/11, 2012 at 9:24 Comment(2)
That's a great solution. Worked for me @SticklerGlycogenesis
You can also simply replace <classpathPrefix>lib/</classpathPrefix> with <classpathPrefix>dependency/</classpathPrefix> without needing the additional config in the maven-dependency-plugin, but it does indeed make it more explicit and obvious this way. Thank you for the great answer :)Gilles
B
10

When you run from Eclipse, Eclipse configures the class path for you. Therefore, you don't run into this issue.

When you are running outside of Eclipse, you need to set up the CLASSPATH either by providing the path to these jar files ie file:/dev/libs/mina-core-2.0.3.jar in the MANIFEST.MF or by adding the -cp option when executing the app. Don't forget that the entries in the class-path in the manifest file are either relative to the JAR in which they are embedded or absolute path to a local file directory.

Your other option is to package it as one jar using the maven assembly plugin jar-with-dependencies.

Base answered 27/4, 2011 at 0:5 Comment(3)
Thank you very much :) This solved my problem! I used the jar-with dependencies.Diondione
much appreciated, that probably saved me hours of searchingThrove
@Throve - Glad to be of help! Happy mavenizing :)Base

© 2022 - 2024 — McMap. All rights reserved.