4

I am learning maven but I am facing problem in importing dependencies, following is my pom.xml file

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myapp.app</groupId>
  <artifactId>myapp</artifactId>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>myapp</name>
 <url>http://maven.apache.org</url>
  <dependencies>
   <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
       <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
       <version>3.3</version>
    </dependency>
  </dependencies>
</project>

Following is my java file

import org.apache.commons.net.ftp.FTPClient;

public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        FTPClient ftp = new FTPClient();
    }
}

I compiled using mvn compile and created jar using mvn package both executed without any error. but when I run application using command

java -cp target/myapp-1.0-SNAPSHOT.jar com.myapp.app.App

it showing following errors

Hello World!
Exception in thread "main" java.lang.NoClassDefFoundError: 
org/apache/commons/net/ftp/FTPClient
        at com.myapp.app.App.main(App.java:16)
 Caused by: java.lang.ClassNotFoundException: 
org.apache.commons.net.ftp.FTPClient
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more
Amit
  • 30,756
  • 6
  • 57
  • 88
AviatorX
  • 492
  • 1
  • 7
  • 17

2 Answers2

4

Reason why it gives noclassfound error is that, when you package it , it doesn't creates a fat/uber jar and jar file in which FTPClient is present, that is not part of your myapp-1.0-SNAPSHOT.jar , hence you get noclassfounderror.

Maven Assembly Plugin helps you to create a fat jar(includes the dependency) jar and creates a runnable jar, where you give your FQCN of Main method. Hence when you run the fat jar it will have all the dependencies and your program will run fine.

Include below plugin in your pom.xml and run mvn package command.

<!-- Maven Assembly Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <!-- get all project dependencies -->
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <!-- MainClass in mainfest make a executable jar -->
                    <archive>
                      <manifest>
                        <mainClass>com.myapp.app.App</mainClass>
                      </manifest>
                    </archive>

                </configuration>
                <executions>
                  <execution>
                    <id>make-assembly</id>
                                        <!-- bind to the packaging phase -->
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                  </execution>
                </executions>
            </plugin>

Note :- here change the mainclass with fully qualified class name of yours.

Let me know if it doesn't work.

Amit
  • 30,756
  • 6
  • 57
  • 88
1

I am able to solve problem adding some code to pom.xml here is the code I added

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>dependency/</classpathPrefix>
                    <mainClass>com.example.MainClass</mainClass>
                </manifest>
            </archive>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-dependencies</id>
                <phase>package</phase>
                <goals>
                    <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                    <useBaseVersion>false</useBaseVersion>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

After compiling and running the project it runs perfectly.

When I am using mvn compile it is just compiling my Main Class but it's not combining dependencies. That's why when I am trying to run JAR file it's giving error ClassNotFound, for this you need to add mvn plugin copy-dependencies and add execution tag to execute mvn command copy-dependencies

SiHa
  • 7,830
  • 13
  • 34
  • 43
AviatorX
  • 492
  • 1
  • 7
  • 17
  • you shoud understand why your are adding a particular peice of code and what was the reason behind the error. i explained that it in my answer , please give it a try and let me know. – Amit Apr 21 '17 at 12:55