jars - java jar classpath command line
Llame a "java-jar MyFile.jar" con la opciĆ³n de ruta de clases adicional (4)
Cuando se utiliza la opción -jar, la opción -cp se ignora. La única forma de establecer la ruta de clases es utilizando el archivo de manifiesto en el contenedor.
Es más fácil simplemente usar la opción -cp, agregar su archivo jar a eso, luego llamar explícitamente a la clase principal.
Además, suponiendo que la carpeta / home / user / java / MyProgram / jar / libs contiene archivos jar (a diferencia de los archivos de clase), esto no funcionará. No puede especificar una carpeta de archivo jar, pero debe especificar cada archivo jar individualmente en classpath (vale la pena escribir un script de shell simple para hacer esto por usted si hay un número significativo de jar).
Creé un archivo jar que contiene todas mis cosas compiladas. Además, mi script de compilación de ant copia las bibliotecas necesarias en una subcarpeta "libs". La estructura se ve así:
MyProgram.jar
libs/
Entonces, cuando intento ejecutar mi programa ahora, aparece el siguiente 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)
¿Por qué pasó esto?
Es un poco complicado. El siguiente script es un intento de obtener el classpath del manifiesto del jar y luego permitirle agregar entradas adicionales de classpath. Tuve resultados mixtos con esto, pero quiero compartir el guión, así que podría ser completamente funcional aquí.
El guion tiene dos nombres
- showmanifest
- calljar
al enlazar los dos archivos junto con
ln calljar showmanifest
con calljar -h puedes ver el uso.
#!/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
Para realizar pruebas únicas e inmediatas de una aplicación, puede vincular simbólicamente los archivos JAR de dependencia necesarios en el directorio que contiene el archivo JAR de la aplicación principal.
Ejemplo (para una aplicación app.jar
que utiliza la biblioteca Eclipse SWT, que en mi caso se instaló en /usr/share/java
):
$ ln -s /usr/share/java/swt.jar .
$ java -jar app.jar
Utiliza -jar
o -cp
, no puede combinar los dos. Si desea colocar JAR adicionales en la ruta de clases, debe colocarlos en el manifiesto principal de JAR y luego utilizar java -jar
o colocar la ruta de clase completa (incluido el JAR principal y sus dependencias) en -cp
y nombrar la clase principal explícitamente en la línea de comando
java -cp ''MyProgram.jar:libs/*'' main.Main
(Estoy usando la sintaxis dir/*
que le dice al comando java
que agregue todos los archivos .jar
de un directorio particular al classpath. Tenga en cuenta que el *
debe estar protegido de la expansión por el shell, por lo que he usado single citas.)
Menciona que está usando Ant para que, por lo tanto, para el enfoque de manifestación alternativa, pueda usar la tarea <manifestclasspath>
ant una vez copiadas las dependencias pero antes de compilar el 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>
Con esto en su lugar, java -jar MyProgram.jar
funcionará correctamente, e incluirá todos los archivos JAR de libs
en el classpath también.