Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoClassDefFoundError on Maven dependency

My first use of Maven and I'm stuck with dependencies.

I created a Maven project with Eclipse and added dependencies, and it was working without problems.

But when I try to run it via command line:

$ mvn package  # successfully completes $ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App # NoClassDefFoundError for dependencies 

It downloads dependencies, successfully builds, but when I try to run it, I get NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonParseException         at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:16)         at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:22)         at tr.edu.hacettepe.cs.b21127113.bil138_4.App.main(App.java:10) Caused by: java.lang.ClassNotFoundException: org.codehaus.jackson.JsonParseException         at java.net.URLClassLoader$1.run(URLClassLoader.java:217)         at java.security.AccessController.doPrivileged(Native Method)         at java.net.URLClassLoader.findClass(URLClassLoader.java:205)         at java.lang.ClassLoader.loadClass(ClassLoader.java:321)         at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)         at java.lang.ClassLoader.loadClass(ClassLoader.java:266)         ... 3 more 

My pom.xml is like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">   <modelVersion>4.0.0</modelVersion>    <groupId>tr.edu.hacettepe.cs.b21127113</groupId>   <artifactId>bil138_4</artifactId>   <version>0.0.1-SNAPSHOT</version>   <packaging>jar</packaging>    <name>bil138_4</name>   <url>http://maven.apache.org</url>    <properties>     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>   </properties>    <dependencies>             <dependency>             <groupId>org.codehaus.jackson</groupId>             <artifactId>jackson-core-asl</artifactId>                </dependency>         <dependency>             <groupId>org.codehaus.jackson</groupId>             <artifactId>jackson-mapper-asl</artifactId>                      </dependency>   </dependencies>   <dependencyManagement>     <dependencies>     <dependency>         <groupId>org.codehaus.jackson</groupId>         <artifactId>jackson-core-asl</artifactId>         <version>1.9.6</version>     </dependency>     <dependency>         <groupId>org.codehaus.jackson</groupId>         <artifactId>jackson-mapper-asl</artifactId>         <version>1.9.6</version>     </dependency>     </dependencies>   </dependencyManagement> </project> 

Can anyone help me?

like image 263
utdemir Avatar asked May 12 '12 23:05

utdemir


2 Answers

By default, Maven doesn't bundle dependencies in the JAR file it builds, and you're not providing them on the classpath when you're trying to execute your JAR file at the command-line. This is why the Java VM can't find the library class files when trying to execute your code.

You could manually specify the libraries on the classpath with the -cp parameter, but that quickly becomes tiresome.

A better solution is to "shade" the library code into your output JAR file. There is a Maven plugin called the maven-shade-plugin to do this. You need to register it in your POM, and it will automatically build an "uber-JAR" containing your classes and the classes for your library code too when you run mvn package.

To simply bundle all required libraries, add the following to your POM:

<project>   ...   <build>     <plugins>       <plugin>         <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-shade-plugin</artifactId>         <version>3.2.4</version>         <executions>           <execution>             <phase>package</phase>             <goals>               <goal>shade</goal>             </goals>           </execution>         </executions>       </plugin>     </plugins>   </build>   ... </project> 

Once this is done, you can rerun the commands you used above:

$ mvn package $ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App 

If you want to do further configuration of the shade plugin in terms of what JARs should be included, specifying a Main-Class for an executable JAR file, and so on, see the "Examples" section on the maven-shade-plugin site.

like image 117
Matt Ryall Avatar answered Oct 12 '22 12:10

Matt Ryall


when I try to run it, I get NoClassDefFoundError

Run it how? You're probably trying to run it with eclipse without having correctly imported your maven classpath. See the m2eclipse plugin for integrating maven with eclipse for that.

To verify that your maven config is correct, you could run your app with the exec plugin using:

mvn exec:java -D exec.mainClass=<your main class> 

Update: First, regarding your error when running exec:java, your main class is tr.edu.hacettepe.cs.b21127113.bil138_4.App. When talking about class names, they're (almost) always dot-separated. The simple class name is just the last part: App in your case. The fully-qualified name is the full package plus the simple class name, and that's what you give to maven or java when you want to run something. What you were trying to use was a file system path to a source file. That's an entirely different beast. A class name generally translates directly to a class file that's found in the class path, as compared to a source file in the file system. In your specific case, the class file in question would probably be at target/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.class because maven compiles to target/classes, and java traditionally creates a directory for each level of packaging.

Your original problem is simply that you haven't put the Jackson jars on your class path. When you run a java program from the command line, you have to set the class path to let it know where it can load classes from. You've added your own jar, but not the other required ones. Your comment makes me think you don't understand how to manually build a class path. In short, the class path can have two things: directories containing class files and jars containing class files. Directories containing jars won't work. For more details on building a class path, see "Setting the class path" and the java and javac tool documentation.

Your class path would need to be at least, and without the line feeds:

target/bil138_4-0.0.1-SNAPSHOT.jar: /home/utdemir/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.6/jackson-core-asl-1.9.6.jar: /home/utdemir/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.9.6/jackson-mapper-asl-1.9.6.jar 

Note that the separator on Windows is a semicolon (;).

I apologize for not noticing it sooner. The problem was sitting there in your original post, but I missed it.

like image 24
Ryan Stewart Avatar answered Oct 12 '22 11:10

Ryan Stewart