Вызовите " java-jar MyFile.jar " с дополнительной опцией classpath
Я создал файл jar, содержащий все мои скомпилированные вещи. Кроме того, мой сценарий сборки ant копирует необходимые библиотеки в подпапку "libs". Структура выглядит так:
MyProgram.jar
libs/
поэтому, когда я пытаюсь запустить мою программу сейчас я получаю следующую ошибку:
java -cp ".:/home/user/java/MyProgram/jar/libs" -jar MyProgram.jar
java.lang.ClassNotFoundException: org.postgresql.Driver
at java.net.URLClassLoader.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)
почему это происходит?
4 ответа:
вы используете или
-jar
или-cp
, вы не можете объединить два. Если вы хотите поместить дополнительные банки в путь к классам, то вы должны либо поместить их в манифест основной банки, а затем использоватьjava -jar
или вы помещаете полный путь к классу (включая основной JAR и его зависимости) в-cp
и имя основного класса явно в командной строкеjava -cp 'MyProgram.jar:libs/*' main.Main
(я использую
dir/*
синтаксис, который сообщаетjava
команда для добавления всех.jar
файлы из определенного каталога в classpath. Обратите внимание, что*
должен быть защищен от расширения оболочкой, поэтому я использовал одинарные кавычки.)вы упомянули, что используете Ant, поэтому для альтернативного подхода к манифесту вы можете использовать ant
<manifestclasspath>
задание после копирование зависимостей, но до строительство банку.<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>
С этим на месте,
java -jar MyProgram.jar
будет работать правильно, и будет включать в себя все элементlibs
JAR файлы на пути к классам, а также.
при использовании параметра-jar параметр-cp игнорируется. Единственный способ установить путь к классу, используя файл manifest в jar.
проще просто использовать параметр-cp, добавить к нему файл jar, а затем явно вызвать основной класс.
кроме того, предполагая, что папка /home/user/java/MyProgram/jar/libs содержит файлы jar (в отличие от файлов классов), это не будет работать. Вы не можете указать папку файла jar, но должны указать каждый файл jar отдельно в файле jar. классов (стоит написать простой shell-скрипт, чтобы сделать это для вас, если есть значительное количество баночек).
Это немного сложнее. Следующий сценарий-это попытка получить путь к классам из манифеста jar, а затем разрешить добавлять дополнительные записи пути к классам. Я смешал результаты с этим, но хочу поделиться сценарием, тем не менее, чтобы он мог быть полностью функциональным здесь.
скрипт имеет два названия
- showmanifest
- calljar
путем жесткого связывания двух файлов вместе с
ln calljar showmanifest
С calljar-h вы можно увидеть использование.
#!/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="" jar="" 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="" jar="" classpath="" pattern="" arguments="" 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= } /^Class-Path:/ { incp=1; cp=; gsub("Class-Path: ","",cp) next } /^ .*$/ && incp { line=substr(,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 " case "" in # options without arguments -h|--help) usage;; # for options with required arguments, an additional shift is required -m|--mainclass) mainclass=; shift;; (--) shift; break;; (-*) echo ": error - unrecognized option " 1>&2; usage;; (*) dir=;shift;break;; esac shift done #echo "argcount=$#" case $# in 0) dir=`dirname "$dir"` jar=`basename "$dir"` show "$dir" "$jar";; 1) jar="" show "$dir" "$jar";; 2) usage;; 3) usage;; *) jar=""; shift; classpath=""; shift; pattern=""; shift; arguments="$@"; #echo "mainclass=${mainclass}" #echo "classpath=${classpath}" #echo calljar "${dir}" "${jar}" "${classpath}" "$pattern" "$arguments" calljar "$dir" "$jar" "$classpath" "$pattern" "$arguments" ;; esac
для быстрого, одноразового тестирования приложения, вы можете просто символически связать необходимые файлы jar зависимостей в каталог, содержащий основной файл JAR приложения.
пример (приложение
app.jar
который использует библиотеку Eclipse SWT, которая в моем случае была установлена в/usr/share/java
):$ ln -s /usr/share/java/swt.jar . $ java -jar app.jar