Incluyendo todos los jar en un directorio dentro del classpath de Java

¿Hay alguna manera de incluir todos los archivos jar dentro de un directorio en el classpath?

Estoy intentando java -classpath lib/*.jar:. my.package.Program java -classpath lib/*.jar:. my.package.Program y no puede encontrar archivos de clase que están ciertamente en esos archivos. ¿Debo agregar cada archivo jar a classpath por separado?

Con Java 6 o posterior, la opción de ruta de clase admite comodines. Tenga en cuenta lo siguiente:

  • Use citas rectas ( " )
  • Use * , not *.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 syntax (donde lib es el directorio que contiene todos los archivos de almacenamiento de Java):

java -cp $(echo lib/*.jar | tr ' ' ':')

(Tenga en cuenta que el uso de un classpath no es compatible con la opción -jar . Consulte también: Ejecutar el archivo jar con múltiples bibliotecas classpath desde el símbolo del sistema )

Comprender los comodines

Del documento de 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 clase foo/* 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 contenga * no coincidirá con los archivos de clase. Para hacer coincidir ambas clases y archivos JAR en un solo directorio foo, use ya sea foo;foo/* o foo/*;foo . El orden elegido determina si las clases y los recursos en foo se cargan antes de los archivos JAR en foo , o viceversa.

Los subdirectorios no se buscan recursivamente. Por ejemplo, foo/* busca archivos JAR solo en foo , no en foo/bar , foo/baz , etc.

El orden en que se enumeran los archivos JAR en un directorio en la ruta de la 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 se pueden enumerar explícitamente en la ruta de la clase.

La expansión de comodines se realiza temprano, antes de la invocación del método principal de un progtwig, en lugar de tarde, durante el proceso de carga de clases. Cada elemento de la ruta de 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 contiene a.jar , b.jar y c.jar , entonces la ruta de clase foo/* se expande en foo/a.jar;foo/b.jar;foo/c.jar , y esa cadena sería el valor de la propiedad del sistema java.class.path .

La variable de entorno CLASSPATH no se trata de manera diferente a la opción de línea de comandos -classpath (o -cp ). Es decir, se respetan los comodines en todos estos casos. Sin embargo, los comodines de la ruta de clase no se respetan en el encabezado Class-Path jar-manifest .

Nota: debido a un error conocido en java 8, los ejemplos de Windows deben usar una barra invertida que precede a las entradas con un asterisco final: https://bugs.openjdk.java.net/browse/JDK-8131329

Debajo de 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 debe usarse solo .


En Linux, lo siguiente funciona:

 java -cp "Test.jar:lib/*" my.package.MainClass 

Los separadores son dos puntos en lugar de punto y coma.

myapp.jar este problema implementando un archivo jar principal myapp.jar que contiene un archivo manifest ( Manifest.mf ) que especifica un classpath con los otros jar requeridos, que luego se implementan junto a él. En este caso, solo necesita declarar java -jar myapp.jar cuando ejecuta el código.

Entonces, si despliega el jar principal en algún directorio y luego pone los juramentos 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 jar para lanzar en un servidor UNIX o en una PC con Windows.

Mi solución en Ubuntu 10.04 usando java-sun 1.6.0_24 teniendo 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 para el parámetro de ruta de clase)

  java -cp $ (para i en lib / *. jar; echo -n $ i:; hecho).  my.main.Class 

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 , bajo el encabezado de sección Understanding class path wildcards . (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 archivos JAR en un directorio determinado, puede usar el comodín * ( no *.jar ).

  • El comodín solo coincide con los JAR, no con los archivos de clase; para obtener todas las clases en un directorio, simplemente termine la entrada de 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 precedencia de classpath habituales. Eg -cp /classes;/jars/*

  • El comodín no buscará JAR en subdirectorios.

  • Los puntos de viñetas anteriores son verdaderos si usa la propiedad del sistema CLASSPATH o los -cp línea de comando -cp o -classpath . Sin embargo, si usa el encabezado del manifiesto JAR de Class-Path (como podría hacer con un archivo de comstackción ant), los comodines no se respetarán.

Sí, mi primer enlace es el mismo que figura en la respuesta máxima (que no tengo esperanzas de adelantar), pero esa respuesta no proporciona mucha explicación más allá del enlace. Dado que ese tipo de comportamiento se desaconseja en Stack Overflow en estos días , pensé en ampliarlo.

Para mí esto funciona en Windows.

 java -cp "/lib/*;" sample 

Para Linux

 java -cp "/lib/*:" sample 

Estoy usando Java 6

Puede probar java -Djava.ext.dirs=jarDirectory http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

Directorio de jarras externas cuando se ejecuta Java

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

Si realmente necesita especificar todos los archivos .jar de forma dinámica, podría utilizar scripts de shell o Apache Ant . Hay un proyecto de commons llamado Commons Launcher que básicamente te permite especificar tu script de inicio como un archivo de comstackción ant (si ves lo que quiero decir).

Luego, puede especificar algo como:

      

En su archivo de comstackción de inicio, que lanzará su aplicación con el classpath correcto.

Si está utilizando Java 6, puede usar comodines en el classpath.

Ahora es posible usar comodines en la definición de la ruta de clases:

 javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes 

Ref: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/

Tenga en cuenta que la expansión de comodines está rota para Java 7 en Windows.

Consulte este problema de StackOverflow para obtener más información.

La solución consiste en poner un punto y coma justo después del comodín. java -cp "somewhere/*;"

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   use -help for a list of possible options 

Estoy bastante seguro de que el comodín no se expande por el caparazón, porque, por ejemplo,

 $ echo './*' ./* 

(Intenté con otro progtwig también, en lugar del echo incorporado, con el mismo resultado).

Creo que es javac quien está tratando de expandirlo, y se comporta de manera diferente si hay un punto y coma en el argumento o no. En primer lugar, puede tratar de expandir todos los argumentos que parecen rutas. Y solo entonces los analizaría, con -cp tomando solo la siguiente ficha. (Tenga en cuenta que com.comsol.aco_1.0.0.jar es el segundo JAR en ese directorio). Eso es toda una suposición.

Esto es

 $ javac -version javac 1.7.0 

Todas las soluciones anteriores funcionan estupendamente si desarrolla y ejecuta la aplicación Java fuera de cualquier IDE como Eclipse o Netbeans.

Si usa Windows 7 y usa Eclipse IDE for Development en Java, puede tener 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 intentes ejecutar Main.java desde Eclipse, se ejecutará sin problemas.

Pero cuando intente ejecutar esto usando el símbolo del sistema después de comstackr Main.java en Eclipse, se dispararán algunos errores extraños diciendo “ClassNotDef Error blah blah”.

¡¡Supongo que estás en el directorio de trabajo de tu código fuente !!

Use la siguiente syntax para ejecutarlo desde el símbolo del sistema:

  1. javac -cp “.; json.jar” Main.java

  2. 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 !!

Para ventanas se requieren cotizaciones y; debe usarse como separador p.ej:

 java -cp "target\\*;target\\dependency\\*" my.package.Main 

Forma abreviada: si su main está dentro de un jar, probablemente necesite una ruta de acceso’jar-aJar / YourJarsName.jar ‘adicional explícitamente declarada para que funcione (aunque’ YourJarsName.jar ‘estaba en el classpath) (o , expresada para responder a la pregunta original que se formuló hace 5 años: no es necesario volver a declarar cada jar explícitamente, pero parece que, incluso con java6, necesita redeclarar su propio jar …)


Long Form: (He hecho esto explícito hasta el punto de que espero que incluso los intrusos a java puedan hacer uso de esto)

Como muchos aquí, estoy usando eclipse para exportar archivos: (Archivo-> Exportar-> ‘Archivo JAR ejecutable’). Hay tres opciones en ofertas de eclipse (Juno) para “manejo de biblioteca”:

 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 usaría opt2 (y opt1 definitivamente se estaba rompiendo), sin embargo, el código nativo en uno de los jar que estoy usando descubrí que se rompe con el práctico truco “jarinjar” que eclipse aprovecha cuando eliges esa opción. Incluso después de darme cuenta de que necesitaba opt3, y luego encontrar esta entrada de StackOverflow, todavía me llevó un 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 llamó a su jar: “fooBarTheJarFile.jar” y todo está configurado para exportar al directorio: “/ theFully / qualifiedPath / toYourChosenDir”.

(lo que significa que el campo ‘Exportar destino’ mostrará: ‘/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar’)

Cuando finalice, encontrará eclipse y luego colocará todas las bibliotecas en una carpeta llamada ‘fooBarTheJarFile_lib’ dentro de ese directorio de exportación, que le proporcionará 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 

A continuación, 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 ‘main (String [] args) {.. .} ‘que deseas correr desde fuera de java)


El inconveniente a tener en cuenta: es que tener ‘fooBarTheJarFile.jar’ dentro de la lista de jar en su classpath declarado no es suficiente. Necesita declarar explícitamente ‘-jar’ y redeclarar la ubicación de ese jar.

por ejemplo, esto rompe:

  java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain 

repasado con rutas relativas:

 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 individual, por ejemplo:

 setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:. 

¡Espero que ayude!

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 

No es una solución directa para poder configurar / * a -cp, pero espero que pueda usar la siguiente secuencia de comandos para facilitar un poco la situación para las rutas de clase dinámicas y los directorios de lib.

  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; 

Con guiones para Linux, podría tener uno similar para Windows también. Si se proporciona un directorio apropiado como entrada para “libDir2Scan4jars”; la secuencia de comandos analizará todos los archivos jar y creará una cadena classpath y la exportará a una variable env “tmpCLASSPATH”.

Debe agregarlos por separado. Alternativamente, si realmente necesita especificar un directorio, puede descomprimir todo en un directorio y agregarlo a su classpath. Sin embargo, no recomiendo este enfoque ya que arriesgas problemas extraños en el control de versiones de classpath y la inmanejabilidad.

Piense en un archivo jar como la raíz de una estructura de directorio. Sí, necesita agregarlos por separado.

Establezca la ruta de clases de una manera conveniente múltiples archivos jar y 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 
    Intereting Posts