Saya membuat file jar yang berisi semua barang saya yang dikompilasi. Selain itu skrip ant build saya menyalin lib yang diperlukan ke dalam subfolder "libs". Strukturnya terlihat seperti ini:
MyProgram.jar
libs/
Jadi ketika saya mencoba menjalankan program saya sekarang saya mendapatkan kesalahan berikut:
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)
Mengapa ini terjadi?
<manifestclasspath>
;
) karena titik dua di Windows digunakan untuk huruf drive. OP menggunakan titik dua dan garis miring dalam pertanyaan mereka, menunjukkan bahwa mereka menggunakan Linux atau Mac.Ketika
-jar
opsi digunakan,-cp
opsi tersebut diabaikan. Satu-satunya cara untuk menyetel classpath adalah menggunakan file manifes di dalam jar.Lebih mudah menggunakan
-cp
opsi, menambahkan file jar Anda ke sana, lalu memanggil kelas utama secara eksplisit.Juga, dengan asumsi
/home/user/java/MyProgram/jar/libs
folder berisi file jar (sebagai lawan file kelas) ini tidak akan berfungsi. Anda tidak dapat menentukan folder file jar tetapi harus menentukan setiap file jar satu per satu di classpath (ada baiknya menulis skrip shell sederhana untuk melakukan ini untuk Anda jika ada sejumlah besar jar).sumber
Ini agak rumit. Skrip berikut adalah upaya untuk mendapatkan classpath dari manifes jar dan kemudian mengizinkan untuk menambahkan entri classpath tambahan. Saya memiliki hasil yang beragam dengan ini tetapi ingin membagikan skrip agar tetap berfungsi penuh di sini.
Skrip ini memiliki dua nama
dengan menautkan kedua file tersebut bersama-sama dengan
dengan calljar -h Anda dapat melihat penggunaannya.
#!/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
sumber
Untuk pengujian cepat dan satu kali suatu aplikasi, Anda cukup menghubungkan file JAR dependensi yang diperlukan ke direktori yang berisi file JAR aplikasi utama.
Contoh (untuk aplikasi
app.jar
yang menggunakan pustaka Eclipse SWT, yang dalam kasus saya dipasang di/usr/share/java
):sumber