Pregunta 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?

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


844
2017-10-20 19:32


origen


Respuestas:


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

  • Use citas rectas")
  • Utilizar *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 : en lugar de ;. Si no puedes 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 un classpath es incompatible con -jar opción. Ver también: Ejecute el archivo jar con múltiples bibliotecas classpath desde el símbolo del sistema)

Comprender los comodines

Desde el Classpath documento:

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, el   entrada de ruta de clase foo/* especifica todos los archivos JAR en el directorio llamado   foo. Una entrada classpath que consiste simplemente en * se 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. A   unir ambas clases y archivos JAR en un solo directorio foo, use cualquiera    foo;foo/* o foo/*;foo. El orden elegido determina si el   clases y recursos en foo se cargan antes de los archivos JAR en foo, o   viceversa.

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

El orden en el que los archivos JAR en un directorio se enumeran en el   La ruta de clase expandida no está especificada y puede variar de plataforma a   plataforma e incluso de momento a momento en la misma máquina. UN   la aplicación bien construida no debe depender de ningún particular   orden. Si se requiere un pedido específico, entonces los archivos JAR pueden ser   enumerado explícitamente en la ruta de clase.

La expansión de comodines se realiza temprano, antes de la invocación de un   principal del programa, en lugar de tarde, durante la carga de clases   procesarse a sí mismo. Cada elemento de la ruta de clase de entrada que contiene un   el comodín se reemplaza por la secuencia de elementos (posiblemente vacía)   generado al enumerar los archivos JAR en el directorio nombrado. por   ejemplo, si el directorio foo contiene a.jar, b.jary c.jar, entonces   el camino 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.

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

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


976
2017-10-20 20:32



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

nota 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.


199
2017-08-14 00:42



Solucionamos este problema implementando un principal archivo jar myapp.jar que contiene un manifiesto (Manifest.mf) archivo que especifica un classpath con los otros jar necesarios, 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 principal jar en algún directorio, y luego poner los frascos dependientes en un 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.


59
2017-10-20 20:08



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

36
2018-03-17 10:55



Respuesta corta: 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 la sección Comprender los comodines de la 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 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. P.ej. -cp /classes;/jars/*

  • El comodín no búsqueda de JAR en subdirectorios.

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

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 es desanimado en desbordamiento de pila estos días, Pensé en ampliarlo.


27
2017-12-21 19:32



Para mí esto funciona en Windows.

java -cp "/lib/*;" sample

Para Linux

java -cp "/lib/*:" sample

estoy usando Java 6


27
2017-10-15 07:43



Puedes 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


21
2018-03-06 21:00



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

20
2018-02-13 17:57



Windows:
 java -cp file.jar; dir / * my.app.ClassName

Linux:
java -cp file.jar: dir / * my.app.ClassName

Recordar:
- Windows el separador de ruta es ";"
- Linux el separador de ruta es ":"
- En Windows, si el argumento cp no contiene espacios en blanco, las "comillas" son opcionales


13
2017-07-18 19:03



Si realmente necesita especificar todos los archivos .jar dinámicamente, podría usar scripts de shell, o Apache Ant. Hay un proyecto de propiedad común llamado Lanzador de Commons que básicamente te permite especificar tu script de inicio como un archivo de compilación de ant (si ves lo que quiero decir).

Luego, puede 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 lanzará su aplicación con el classpath correcto.


8
2017-10-20 19:55



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

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


8
2017-11-01 22:31