Ejecute un archivo JAR desde la línea de comando y especifique classpath

115

He compilado un archivo JAR y he especificado la clase principal en el manifiesto (utilicé la función de exportación de Eclipse ). Mis dependencias están todas en un directorio etiquetado lib. Parece que no puedo obtener una respuesta directa sobre cómo ejecutar mi archivo JAR mientras especifico que debe usar lib/*como classpath.

He intentado:

]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main

etc ...

Cada uno da un error que dice:

Error: Could not find or load main class ....

o da la NoClassDefFoundErrorindicación de que no se encuentran las bibliotecas.

Incluso intenté rehacer el archivo JAR e incluí el libdirectorio y el contenido, pero todavía no hay dados ...

¿Cómo puedo ejecutar un archivo JAR desde la línea de comando y especificar la ruta de clase a usar?

SnakeDoc
fuente

Respuestas:

204

Cuando lo especifique , se ignorará -jarel -cpparámetro.

De la documentación :

Cuando utiliza esta opción, el archivo JAR es el origen de todas las clases de usuario y se ignoran otras configuraciones de ruta de clases de usuario.

Tampoco puede "incluir" los archivos jar necesarios en otro archivo jar (necesitaría extraer su contenido y poner los archivos .class en su archivo jar)

Tienes dos opciones:

  1. incluir todos los archivos jar del libdirectorio en el manifiesto (puede usar rutas relativas allí)
  2. Especifique todo ( incluido su jar) en la línea de comandos usando -cp:
    java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
un caballo sin nombre
fuente
22
; en lugar de: si usa Windows de la siguiente manera java -cp MyJar.jar; lib / * com.somepackage.subpackage.Main
Error
Tampoco puede "incluir" los archivos jar necesarios en otro archivo jar. Seguro que puede. Si es para uso interno (es decir, espera que el usuario tenga alguna habilidad técnica, etc.) puede simplemente pedir que el paso 1, antes de intentar ejecutar el jar, sea ejecutar unzip MyJar.jar lib/*.jar. Luego, como sugieres, pueden correrjava -cp MyJar.jar:lib/* ...
Roger
3
lo malo es que es un caso de uso común ejecutar un jar uber "todo incluido" con una referencia a un archivo de propiedades externo específico del servidor. Obviamente no es un bloqueador, pero ciertamente un comando menos detallado si puede usar el -jar y no tener que especificar el principal
Andrew Norman
Me tomó un tiempo darme cuenta. Y se necesitan aproximadamente 6 líneas para cargar un archivo log4j explícitamente. Otro error de Java que nunca se solucionará.
Tuntable
1
Tenga en cuenta que el manifiesto Class-Path solo se puede utilizar para cargar archivos jar. No se puede utilizar para buscar log4j3.xml, por ejemplo. Me entendiste bien.
Tuntable
34

Ejecute un archivo jar y especifique una ruta de clase como esta:

java -cp <jar_name.jar:libs/*> com.test.App

jar_name.jar es el nombre completo del JAR que desea ejecutar

libs/* es un camino a sus JAR de dependencia

com.test.Appes el nombre completo de la clase del JAR que tiene el main(String[])método

El jar y el jar dependiente deben tener permisos de ejecución.

Sid
fuente
10

Puede hacer esto en unix shell:

java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

Puede hacer esto en Windows PowerShell:

java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main
alquitranes
fuente
4

Alternativamente, use el manifiesto para especificar la ruta de clase y la clase principal si lo desea, por lo que no necesita usar -cpo especificar la clase principal. En su caso, contendría líneas como esta:

Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar

Desafortunadamente, debe especificar cada jar en el manifiesto (no es un gran problema, ya que solo lo hace una vez, y puede usar un script para compilar el archivo o usar una herramienta de compilación como ANT o Maven o Gradle). Y la referencia tiene que ser un directorio relativo o absoluto al lugar donde ejecuta java -jar MyJar.jar.

Entonces ejecútalo con

java -jar MyJar.jar
HankCa
fuente
Creo que Class-Path necesita hacer referencia a archivos dentro del jar externo. No pude hacer que esto funcione en general, para referirme a archivos de configuración fuera de MyJar.jar.
Tuntable
0

Puede hacer un Runtime.getRuntime.exec (comando) para reiniciar el jar, incluida la ruta de clase con args.

Tim de Vries
fuente