programacion - Incluyendo todos los tarros en un directorio dentro de la ruta de clase de Java
libro de programacion en java netbeans pdf (22)
¿Hay alguna manera de incluir todos los archivos jar en un directorio en el classpath?
Estoy probando java -classpath lib/*.jar:. my.package.Program
java -classpath lib/*.jar:. my.package.Program
y no puede encontrar archivos de clase que ciertamente se encuentran en esos archivos java -classpath lib/*.jar:. my.package.Program
. ¿Necesito agregar cada archivo jar a la ruta de clase por separado?
A quien le interese,
Encontré este extraño comportamiento en Windows bajo un shell MSYS / MinGW.
Trabajos:
$ javac -cp ''.;c:/Programs/COMSOL44/plugins/*'' Reclaim.java
No funciona
$ javac -cp ''c:/Programs/COMSOL44/plugins/*'' Reclaim.java
javac: invalid flag: c:/Programs/COMSOL44/plugins/com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options
Estoy bastante seguro de que el comodín no está expandido por el shell, porque, por ejemplo,
$ echo ''./*''
./*
(Lo intenté con otro programa también, en lugar del echo
incorporado, con el mismo resultado).
Creo que es javac
que está intentando expandirlo, y se comporta de manera diferente tanto si hay un punto y coma en el argumento como si no. Primero, puede estar intentando expandir todos los argumentos que parecen caminos. Y solo entonces los analizaría, con -cp
tomando solo el siguiente token. (Tenga en cuenta que com.comsol.aco_1.0.0.jar
es el segundo JAR en ese directorio). Eso es todo una conjetura.
Esto es
$ javac -version
javac 1.7.0
Bajo Windows esto funciona:
java -cp "Test.jar;lib/*" my.package.MainClass
y esto no funciona:
java -cp "Test.jar;lib/*.jar" my.package.MainClass
observe el * .jar, por lo que el comodín * se debe usar solo .
En Linux, los siguientes trabajos:
java -cp "Test.jar:lib/*" my.package.MainClass
Los separadores son dos puntos en lugar de puntos y coma.
Establezca el classpath de una manera adecuada para múltiples archivos jar y los archivos de clase del directorio actual.
CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar;
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH
Forma corta: si su main está dentro de un jar, probablemente necesitará un ''-jar pathTo / yourJar / YourJarsName.jar'' adicional declarado explícitamente para que funcione (incluso aunque ''YourJarsName.jar'' estaba en el classpath) (o , expresado para responder a la pregunta original que se hizo hace 5 años: no es necesario volver a declarar cada frasco explícitamente, pero parece que, incluso con java6, debe volver a declarar su propio frasco ...)
Forma larga: (He hecho esto explícito hasta el punto de que espero que incluso los intrusos de Java puedan hacer uso de esto)
Como muchos aquí, estoy usando eclipse para exportar archivos jar: (Archivo-> Exportar -> ''Archivo JAR ejecutable''). Hay tres opciones en las ofertas de eclipse (manejo de bibliotecas) (Juno):
opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"
Normalmente, yo uso opt2 (y opt1 definitivamente se estaba rompiendo), sin embargo, el código nativo en uno de los frascos que estoy usando descubrí rupturas con el práctico truco "jarinjar" que eclipsa el eclipse cuando eliges esa opción. Incluso después de darme cuenta de que necesitaba opt3, y luego encontrar esta entrada de , todavía me tomó algo de tiempo descubrir cómo lanzar mi principal fuera de eclipse, así que esto es lo que funcionó para mí, ya que es útil para otros ...
Si nombró su archivo jar: "fooBarTheJarFile.jar" y todo está configurado para exportar a la dir: "/ theFully / qualifiedPath / toYourChosenDir".
(lo que significa que el campo ''Destino de exportación'' se leerá: ''/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar'')
Una vez que haya finalizado, encontrará eclipse y luego colocará todas las bibliotecas en una carpeta llamada ''fooBarTheJarFile_lib'' dentro de ese directorio de exportación, brindándole algo como:
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar
Luego puede iniciar desde cualquier lugar de su sistema con:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(Para Java Newbies: ''package.path_to.the_class_with.your_main'' es la ruta del paquete declarada que encontrará en la parte superior del archivo ''TheClassWithYourMain.java'' que contiene el ''main (String [] args) {.. .} ''que desea ejecutar desde fuera de Java)
El inconveniente a tener en cuenta: es que tener ''fooBarTheJarFile.jar'' en la lista de archivos jar en su classpath declarado no es suficiente. Debe declarar explícitamente ''-jar'' y volver a declarar la ubicación de ese contenedor.
por ejemplo, esto se rompe:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain
replanteado con caminos relativos:
cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS: java -cp "fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" -jar package.path_to.the_class_with.your_main.TheClassWithYourMain
WORKS: java -cp ".;fooBarTheJarFile_lib/*" -jar fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(usando la versión de Java "1.6.0_27"; a través de OpenJDK 64-Bit Server VM en ubuntu 12.04)
La única forma en que sé cómo hacerlo es individualmente, por ejemplo:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
¡Espero que ayude!
Mi solución en Ubuntu 10.04 usando java-sun 1.6.0_24 con todos los archivos jar en el directorio "lib":
java -cp .:lib/* my.main.Class
Si esto falla, el siguiente comando debería funcionar (imprime todos los * .jars en el directorio lib al parámetro classpath)
java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class
Necesitas agregarlos todos por separado. Alternativamente, si realmente solo necesita especificar un directorio, puede descomprimir todo en un directorio y agregarlo a su classpath. Sin embargo, no recomiendo este enfoque, ya que corre el riesgo de tener problemas extraños en las versiones de classpath y la inmanejabilidad.
No es una solución directa para poder configurar / * en -cp, pero espero que pueda usar el siguiente script para aliviar un poco la situación de los directorios dinámicos de rutas de clases y bibliotecas.
libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use ~> java -cp /$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi;
Scripted para Linux, también podría tener uno similar para Windows. Si se proporciona el directorio adecuado como entrada para "libDir2Scan4jars"; la secuencia de comandos escaneará todos los archivos jar, creará una cadena de ruta de clase y la exportará a una variable env "tmpCLASSPATH".
Para Windows se requieren cotizaciones y; Se debe utilizar como separador. p.ej:
java -cp "target//*;target//dependency//*" my.package.Main
Para mi esto funciona en windows.
java -cp "/lib/*;" sample
Para linux
java -cp "/lib/*:" sample
Estoy usando java 6
Piense en un archivo jar como la raíz de una estructura de directorios. Sí, necesitas agregarlos todos por separado.
Puede probar java -Djava.ext.dirs=jarDirectory
http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html
Directorio para jars externos cuando se ejecuta java
Respuesta corta: java -classpath lib/*:. my.package.Program
java -classpath lib/*:. my.package.Program
Oracle proporciona documentación sobre el uso de comodines en classpaths aquí para Java 6 y aquí para Java 7 , en la sección titulada Entendiendo los comodines de ruta de clase . (Mientras escribo esto, las dos páginas contienen la misma información). Aquí hay un resumen de los aspectos más destacados:
En general, para incluir todos los JAR en un directorio determinado, puede usar el comodín
*
( no*.jar
).El comodín solo coincide con JAR, no con archivos de clase; para obtener todas las clases en un directorio, simplemente finalice la entrada classpath en el nombre del directorio.
Las dos opciones anteriores se pueden combinar para incluir todos los archivos JAR y de clase en un directorio, y se aplican las reglas de prioridad de classpath habituales. Por ejemplo,
-cp /classes;/jars/*
El comodín no buscará archivos JAR en los subdirectorios.
Los puntos de viñeta anteriores son verdaderos si utiliza la propiedad del sistema
CLASSPATH
o los-cp
línea de comando-cp
o-classpath
. Sin embargo, si usa el encabezado de manifiesto JAR deClass-Path
(como podría hacer con un archivo de compilación ant), no se aceptarán los comodines.
Sí, mi primer enlace es el mismo que se proporciona en la respuesta con la puntuación más alta (que no tengo esperanza de adelantar), pero esa respuesta no proporciona mucha explicación más allá del enlace. Dado que este tipo de comportamiento no se discouraged en en estos días , pensé en ampliarlo.
Si está utilizando Java 6, entonces puede usar comodines en la ruta de clase.
Ahora es posible usar comodines en la definición de classpath:
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
Si realmente necesita especificar todos los archivos .jar dinámicamente, puede usar shell scripts o Apache Ant . Hay un proyecto común llamado Commons Launcher que básicamente le permite especificar su secuencia de comandos de inicio como un archivo de compilación (si ve lo que quiero decir).
Entonces, puedes especificar algo como:
<path id="base.class.path">
<pathelement path="${resources.dir}"/>
<fileset dir="${extensions.dir}" includes="*.jar" />
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
En su archivo de compilación de inicio, que iniciará su aplicación con la ruta de clase correcta.
Tenga en cuenta que la expansión de comodines está rota para Java 7 en Windows.
Echa un vistazo a este problema para obtener más información.
La solución es poner un punto y coma justo después del comodín. java -cp "somewhere/*;"
Todas las soluciones anteriores funcionan bien si desarrolla y ejecuta la aplicación Java fuera de cualquier IDE como Eclipse o Netbeans.
Si tiene Windows 7 y usó el IDE de Eclipse para desarrollo en Java, es posible que tenga problemas si usa el Símbolo del sistema para ejecutar los archivos de clase creados dentro de Eclipse.
Por ejemplo, su código fuente en Eclipse tiene la siguiente jerarquía de paquetes: edu.sjsu.myapp.Main.java
Tienes json.jar como una dependencia externa para Main.java
Cuando intente ejecutar Main.java desde Eclipse, se ejecutará sin problemas.
Pero cuando intentas ejecutar esto usando el símbolo del sistema después de compilar Main.java en Eclipse, disparará algunos errores extraños que dicen "Error de ClassNotDef blah blah".
¡Supongo que estás en el directorio de trabajo de tu código fuente!
Use la siguiente sintaxis para ejecutarlo desde el símbolo del sistema:
javac -cp ".; json.jar" Main.java
java -cp ".; json.jar" edu.sjsu.myapp.Main
[No te pierdas el. encima]
Esto se debe a que ha colocado Main.java dentro del paquete edu.sjsu.myapp y java.exe buscará el patrón exacto.
Espero eso ayude !!
Usando Java 6 o posterior, la opción classpath admite comodines. Tenga en cuenta lo siguiente:
- Usa comillas rectas (
"
) - Usa
*
, no*.jar
Windows
java -cp "Test.jar;lib/*" my.package.MainClass
Unix
java -cp "Test.jar:lib/*" my.package.MainClass
Esto es similar a Windows, pero usa :
lugar de ;
. Si no puede usar comodines, bash
permite la siguiente sintaxis (donde lib
es el directorio que contiene todos los archivos de almacenamiento de Java):
java -cp $(echo lib/*.jar | tr '' '' '':'')
(Tenga en cuenta que usar una ruta de -jar
es incompatible con la opción -jar
. Ver también: ejecutar el archivo jar con varias bibliotecas de ruta de clase desde el símbolo del sistema )
Entendiendo los comodines
Del documento Classpath :
Las entradas de ruta de clase pueden contener el carácter comodín de nombre base
*
, que se considera equivalente a especificar una lista de todos los archivos en el directorio con la extensión.jar
o.JAR
. Por ejemplo, la entrada de la ruta de clasefoo/*
especifica todos los archivos JAR en el directorio llamado foo. Una entrada classpath que consiste simplemente en*
expande a una lista de todos los archivos jar en el directorio actual.Una entrada de ruta de clase que contiene
*
no coincidirá con los archivos de clase. Para hacer coincidir las clases y los archivos JAR en un solo directorio foo, usefoo;foo/*
ofoo/*;foo
. El orden elegido determina si las clases y los recursos enfoo
se cargan antes que los archivos JAR enfoo
, o viceversa.Los subdirectorios no se buscan de forma recursiva. Por ejemplo,
foo/*
busca archivos JAR solo enfoo
, no enfoo/bar
,foo/baz
, etc.El orden en que se enumeran los archivos JAR en un directorio en la ruta de clase expandida no se especifica y puede variar de una plataforma a otra e incluso de un momento a otro en la misma máquina. Una aplicación bien construida no debe depender de ningún orden en particular. Si se requiere un orden específico, los archivos JAR pueden enumerarse explícitamente en la ruta de clase.
La expansión de los comodines se realiza antes, antes de la invocación del método principal de un programa, y no tarde, durante el proceso de carga de clases. Cada elemento de la ruta de la clase de entrada que contiene un comodín se reemplaza por la secuencia (posiblemente vacía) de elementos generados al enumerar los archivos JAR en el directorio nombrado. Por ejemplo, si el directorio
foo
contienea.jar
,b.jar
yc.jar
, la ruta de clasefoo/*
se expandirá enfoo/a.jar;foo/b.jar;foo/c.jar
, y esa cadena sería el valor de la propiedad del sistemajava.class.path
.La variable de entorno
CLASSPATH
no se trata de manera diferente de la opción de línea de comandos-classpath
(o-cp
). Es decir, los comodines son honrados en todos estos casos. Sin embargo, los comodines de ruta de clase no se respetan en el encabezado deClass-Path jar-manifest
.
Nota: debido a un error conocido en Java 8, los ejemplos de Windows deben usar una barra invertida que preceda a las entradas con un asterisco final: https://bugs.openjdk.java.net/browse/JDK-8131329
clase de wepapp:
> mvn clean install
> java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2
myapp.jar
este problema implementando un archivo jar principal myapp.jar
que contiene un archivo de manifiesto ( Manifest.mf
) que especifica una ruta de clase con los otros archivos jar necesarios, que luego se implementan a su lado. En este caso, solo necesita declarar java -jar myapp.jar
cuando ejecute el código.
Entonces, si implementas el jar
principal en algún directorio y luego pones los jarros dependientes en una carpeta lib
debajo de eso, el manifiesto se ve así:
Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar
NB: esto es independiente de la plataforma: podemos usar los mismos archivos jar para iniciar en un servidor UNIX o en una PC con Windows.
Correcto :
java -classpath "lib/*:." my.package.Program
Incorrecto:
java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:." my.package.Program
java -classpath "lib/*.jar:." my.package.Program
java -classpath lib/*:. my.package.Program
Windows :
java -cp file.jar; dir / * my.app.ClassName
Linux :
java -cp file.jar: dir / * my.app.ClassName
Recordar:
- El separador de ruta de Windows es " ; "
- El separador de ruta de Linux es " : "
- En Windows, si el argumento cp no contiene espacios en blanco, las "comillas" son opcionales