2010-02-09 21 views
9

Estoy buscando hacer algo que pensé que no iba a ser difícil.Java -jar: acceder al archivo de configuración externa

Tengo una aplicación que me gustaría empaquetar como un contenedor porque tengo ~ 30 dependencias y me gustaría poder implementar un único archivo.

Tengo algunos archivos de configuración, un archivo de propiedades y un archivo de configuración de primavera, y mi archivo log4 props, que me gustaría tener externos al contenedor. Supongo que esperaba que si los colocaba en el mismo directorio que el contenedor los encontraría cuando se ejecutaran, pero no es así.

Durante el desarrollo, tengo estos archivos en la raíz del classpath para mi proyecto eclipse y la aplicación los encuentra muy bien. Siento que me falta algún aspecto clave de la teoría jar/classpath ...

así que lo que quiero es poder poner los archivos de configuración y el jar en el mismo directorio y hacer que la aplicación encuentre los archivos de configuración cuando lo ejecuto con la cosa java-jar estándar.

¿No hay una manera simple de lograr esto?

Respuesta

11

voy a preservar para la posteridad mi solución a este problema.

Creo que es posible que esperaba que java -jar hiciera algo que no hace.

Si usa el comando java normal, puede incluir el jar en el classpath y terminará con prácticamente lo mismo que java -jar, solo tiene que nombrar específicamente la clase que desea usar.Se ve así:

java -cp .:path/to/Jar.jar com.company.package.Class arg1=val1 arg2=val2 .... 

Lo más probable es que va a construir una secuencia de comandos para iniciar el programa para usted de todos modos, por lo que la complejidad añadida de la llamada línea de comandos en realidad no es gran cosa, ya que' Solo lo construiré una vez de todos modos.

Verás que incluí '.' como el primer elemento en el classpath, lo que significa que cualquier cosa en el mismo directorio que el jar se incluirá también en el classpath. Por supuesto, todo lo que está dentro del jar se incluye también en classpath, ya que el propio jar también se encuentra en el classpath.

También verás que he mostrado cómo puedes seguir entregando argumentos en la línea de comandos. Esto era algo de lo que no estaba seguro cuando comencé, pero funciona como se esperaba.

Estoy seguro de que esto es solo conocimiento básico de implementación de Java, pero me faltaba por alguna razón.

Espero que esto ayude a alguien más. Ciertamente me habría ahorrado mucho tiempo si alguien hubiera podido decir "no se moleste en tratar de hacer que la cosa funcione, solo use el método -cp" ...

4

Tienes que agregar "." al classpath del archivo jar que está creando para su aplicación.

Así, en el manifiesto, esperaría ver

Main-Class: some.full.Name 
Class-Path: . needed-lib.jar other-lib.jar 

Entonces, al ejecutar su aplicación mediante la ejecución de

java -jar myapp.jar 

realmente utiliza

java -classpath .;needed-lib.jar;other-lib.jar some.full.Name 

esta manera cualquier archivo en el directorio con el archivo myapp.jar también estará en el classpath. Ese classpath es relativo a la ubicación del jar que lo contiene.

Log4j para uno espera que el archivo de configuración log4j.xml esté en classpath. Si no está utilizando el nombre log4j.xml, también debe agregar una propiedad del sistema a su comando de inicio para indicarle a la biblioteca log4j que busque un nombre diferente.

No estoy seguro de qué espera Spring para los archivos de configuración. Y la carga del archivo de propiedades depende del mecanismo utilizado para cargar el archivo. El uso de un FileReader o InputStream no utiliza el mecanismo classpath en absoluto. En ese caso, debe saber dónde espera la aplicación que el archivo esté relacionado con el directorio de trabajo actual.

+0

Gracias por la respuesta Jay R . mi Manifiesto tiene esto en él, que creo que es lo que sugieres: Manifiesto-Version: 1.0 principal clase: Class-Path:. – Joel

+0

Agregué más a mi respuesta que espero ayude. –

+0

Gracias de nuevo por su respuesta Jay R. Su ayuda es muy apreciada. No estoy teniendo mucha suerte. Estoy usando el archivo log4j.properties en lugar de la configuración xml, pero creo que siempre que el archivo esté en classpath log4j debería encontrarlo bien. El mismo trato con el archivo de configuración de primavera: llamo a mine spring.xml, pero mientras esté en el classpath no debería haber ningún problema. Mi MANIFEST.MF está siendo generado por el exportador "Ejecutable de Runnable ..." de Eclipse pero se ve exactamente como el de la muestra. No estoy seguro de lo que está pasando aquí. Gracias de nuevo por su comprensión. – Joel

2

Creo que puede hacer esto con un manifiesto en el jar para especificar el classpath que debería usar.

Editado: algo como This

Cuestiones relacionadas