Call "java -jar MyFile.jar" with the optional classpath option

I created a jar file containing all my compiled materials. In addition, my ant build script copies the necessary libraries to the "libs" subfolder. The structure is as follows:

MyProgram.jar libs/ 

So, when I try to run my program, I get the following error:

 java -cp ".:/home/user/java/MyProgram/jar/libs" -jar MyProgram.jar java.lang.ClassNotFoundException: org.postgresql.Driver 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) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:186) at database.PostgresQL.getConnection(PostgresQL.java:38) at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:19) at main.Main.calculateCorrelationMatrix(Main.java:51) at main.Main.main(Main.java:28) java.lang.NullPointerException at recommender.dao.Creative2IdxDAO.createCreatives2Idx(Creative2IdxDAO.java:25) at main.Main.calculateCorrelationMatrix(Main.java:51) at main.Main.main(Main.java:28) 

Why is this happening?

+67
java classpath jar
Apr 10 '13 at 15:58
source share
4 answers

You use either -jar or -cp , you cannot combine these two. If you want to put additional JARs in the classpath, then you must either put them in the main JAR manifest and then use java -jar or you put the full class path (including the main JAR and its dependencies) in -cp and name the main class explicitly on the command line

 java -cp 'MyProgram.jar:libs/*' main.Main 

(I use the dir/* syntax, which tells the java command to add all .jar files from a specific directory to the class path. Note that * must be protected from expansion by the shell, so I used single quotes.)

You mentioned that you are using Ant, so for an alternative manifest, you can use the Ant <manifestclasspath> task after copying the dependencies, but before creating the JAR.

 <manifestclasspath property="myprogram.manifest.classpath" jarfile="MyProgram.jar"> <classpath> <fileset dir="libs" includes="*.jar" /> </classpath> </manifestclasspath> <jar destfile="MyProgram.jar" basedir="classes"> <manifest> <attribute name="Main-Class" value="main.Main" /> <attribute name="Class-Path" value="${myprogram.manifest.classpath}" /> </manifest> </jar> 

At the same time, java -jar MyProgram.jar will work correctly and will include all the libs JAR files in the class path.

+123
Apr 10 '13 at 4:07
source share

When the -jar option is -cp option -cp ignored. The only way to set the classpath is to use the manifest file in the bank.

It's easier to just use -cp , add your jar file to it, and then explicitly call the main class.

Also, assuming that the folder /home/user/java/MyProgram/jar/libs contains jar files (as opposed to class files), this will not work. You cannot specify the folder of the jar file, but you must specify each jar file separately in the classpath (it is worth writing a simple shell script to do this for you if there are a significant number of jar files).

+16
Apr 10 '13 at
source share

This is a bit complicated. The following script is an attempt to get the class path from the jar manifest, and then allow additional entries to be added to the classpath. I had mixed results with this, but want to share the script nonetheless, so that it can be fully functional here.

script has two names

  • showmanifest
  • calljar

by linking two files together with

 ln calljar showmanifest 

with calljar -h you can see the usage.

 #!/bin/bash #set -x # show the manifest of a jar file # 2012-07-18 # author WF # # show usage # usage() { echo "usage: showmanifest (jarfile | directory jarfile) " 1>&2 echo "usage: calljar directory jarfile classpath pattern arguments" 1>&2 echo " -h|--help " 1>&2 echo " show this help and exit" 1>&2 echo " -m|--mainclass javaclass" 1>&2 echo " mainclass to use (otherwise manifest is inspected)" 1>&2 exit 1 } # # show the manifest of the given jar file # show() { dir="$1" jar="$2" fulljar=`find "$dir" -name "$jar"` cd /tmp mkdir show$$ cd show$$ jar xvf $fulljar META-INF/MANIFEST.MF cat META-INF/MANIFEST.MF cd /tmp rm -rf show$$ } # # show the classpath of the manifest # calljar() { dir="$1" jar="$2" classpath="$3" pattern="$4" arguments="$5" cmd=`show "$dir" "$jar" | awk -v extracp="$classpath" -v dir="$dir" -v pattern="$pattern" -v jar="$jar" -v mainclass="$mainclass" -v args="$arguments" ' /Main-Class: / { if (mainclass=="") mainclass=$2 } /^Class-Path:/ { incp=1; cp=$0; gsub("Class-Path: ","",cp) next } /^ .*$/ && incp { line=substr($0,2) # remove carriage return (if any) cp=cp line } END { # we do not like carriage returns gsub("\\r","",cp) gsub("\\r","",mainclass) # we do not like blanks ... gsub(" ","",cp) gsub(pattern,":"dir"/"pattern,cp) print "java -cp " extracp cp ":"dir"/"jar " " mainclass " " args } '` #echo $cmd $cmd } # echo $# arguments found: $* # parse command line options while true; do # echo "option $1" case "$1" in # options without arguments -h|--help) usage;; # for options with required arguments, an additional shift is required -m|--mainclass) mainclass=$2; shift;; (--) shift; break;; (-*) echo "$0: error - unrecognized option $1" 1>&2; usage;; (*) dir=$1;shift;break;; esac shift done #echo "argcount=$#" case $# in 0) dir=`dirname "$dir"` jar=`basename "$dir"` show "$dir" "$jar";; 1) jar="$1" show "$dir" "$jar";; 2) usage;; 3) usage;; *) jar="$1"; shift; classpath="$1"; shift; pattern="$1"; shift; arguments="$@"; #echo "mainclass=${mainclass}" #echo "classpath=${classpath}" #echo calljar "${dir}" "${jar}" "${classpath}" "$pattern" "$arguments" calljar "$dir" "$jar" "$classpath" "$pattern" "$arguments" ;; esac 
0
Apr 08 '14 at 17:19
source share

For quick one-time application tests, you can simply symbolize the required dependency JAR files in the directory containing the main application JAR file.

Example (for the app.jar application that uses the Eclipse SWT library, which in my case was installed in /usr/share/java ):

 $ ln -s /usr/share/java/swt.jar . $ java -jar app.jar 
0
Oct 21 '15 at 11:31
source share



All Articles