59
votes

I have a Maven project which generates a jar file and copies all dependencies to target/lib folder. I want to execute this project on client's machine (windows). So, I copied myproject.jar to C:\xyz folder and all dependencies to C:\xyz\lib folder. How do I execute this project from client's command prompt? I tried to use java -cp lib\*.jar -jar myproject.jar from C:\xyz folder but it throws following error.

Exception in thread "main" java.lang.NoClassDefFoundError: lib\commons-codec-1/3/jar
Caused by: java.lang.ClassNotFoundException: lib\commons-codec-1.3.jar
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    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)
Could not find the main class: lib\commons-codec-1.3.jar.  Program will exit.

I think if I specify all dependencies in classpath (like java -cp lib\dep1.jar;dep2.jar), it will get rid of the problem but I don't want to do this as I have 40 libraries already and it might grow in future releases. Is there a better way to do this?

9

9 Answers

15
votes

Let maven generate a batch file to start your application. This is the simplest way to this.

You can use the appassembler-maven-plugin for such purposes.

72
votes

You cannot use both -jar and -cp on the command line - see the java documentation that says that if you use -jar:

the JAR file is the source of all user classes, and other user class path settings are ignored.

You could do something like this:

java -cp lib\*.jar;. myproject.MainClass

Notice the ;. in the -cp argument, to work around a Java command-line bug. Also, please note that this is the Windows version of the command. The path separator on Unix is :.

62
votes

Using java 1.7, on UNIX -

java -cp myjar.jar:lib/*:. mypackage.MyClass

On Windows you need to use ';' instead of ':' -

java -cp myjar.jar;lib/*;. mypackage.MyClass
8
votes

Regardless of the OS the below command should work:

java -cp "MyJar.jar;lib/*" com.mainClass

Always use quotes and please take attention that lib/*.jar will not work.

3
votes

You can use maven-assembly-plugin, Here is the example from the official site: https://maven.apache.org/plugins/maven-assembly-plugin/usage.html

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <mainClass>your main class</mainClass>
                </manifest>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id> <!-- this is used for inheritance merges -->
                <phase>package</phase> <!-- bind to the packaging phase -->
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
2
votes

a possible solution could be

create a batch file

there do a loop on lib directory for all files inside it and set each file unside lib on classpath

then after that run the jar

source for loop in batch file for info on loops

1
votes

There are several options.

The easiest is likely the exec plugin.

You can also generate a jar containing all the dependencies using the assembly plugin.

Lastly, you can generate a file with the classpath in it using the dependency:classpath goal.

1
votes

I was running into the same issue but was able to package all dependencies into my jar file using the Maven Shade Plugin

-2
votes

This will not work java -cp lib\*.jar -jar myproject.jar. You have to put it jar by jar.

So in case of commons-codec-1.3.jar.

java -cp lib/commons-codec-1.3.jar;lib/next_jar.jar and so on.

The other solution might be putting all your jars to ext directory of your JRE. This is ok if you are using a standalone JRE. If you are using the same JRE for running more than one application I do not recommend doing it.