2009-02-19 35 views
5

Creé una aplicación Java autónoma que tiene un conjunto de dependencias (Apache Commons libs, etc.) así como una dependencia en el framework Spring, que a su vez tiene un montón de dependencias.Empaquetar y ejecutar una aplicación Java con dependencias de primavera

Lo construí en Eclipse, donde funciona bien. Ahora necesito implementarlo en producción, así que estoy tratando de encontrar la mejor manera de empaquetarlo con todas las dependencias y también cómo invocarlo (se invocará desde la línea de comandos).

La fuerza bruta sería exportar mi proyecto como un contenedor, encontrar todos los archivos dependientes (y sus dependencias), copiarlos a un directorio común, escribir un script de shell que incluya cada uno en el classpath y ejecutarlo. Obviamente eso parece estúpido y tedioso.

¿Debo usar Ant, Maven? ¿Debo empaquetar todos los frascos de primavera dependientes en un solo archivo grande? Cualquier consejo sobre cómo lidiar con esto sería útil.

Respuesta

4

La implementación de Java sigue siendo estúpida y tediosa en 2009. Por lo tanto, la opción habitual es escribir este pequeño script. Si coloca todos sus archivos JAR en un directorio (por ejemplo, lib\), puede usar un script común que construye el classpath automáticamente (consulte this blog entry). Sugiero agregar un cd /d %~dp0 al principio para hacer un cd en el directorio del script.

Maven 2 tiene un complemento que puede armar su aplicación en un "super JAR" (mvn assembly:assembly). Esto funciona a menos que utilice el controlador JCC de DB2 (que contiene paquetes "COM.ibm. " que se convierten en com.ibm. -> ClassNotFoundException).

La última solución, si ya tiene un ANT build.xml que funciona, es descomprimir todos los JAR dependientes y crear un "super JAR" usted mismo.

1

Descubrimos que la mejor solución para el manejo y empaquetado de dependencias es usar Maven con el complemento Assembly. Esto proporciona un medio muy elegante para empaquetar sus proyectos, junto con todas las dependencias de tiempo de ejecución y scripts de respaldo en una distribución binaria. Una de las mayores ventajas del uso de ensamblajes es que es posible dividir sus proyectos en componentes distintos según la necesidad. Si está utilizando Spring Integration es bastante común, tendría componentes separados para dividir en varias máquinas. El complemento de ensamblaje le permite configurar esto según sus requisitos.

0

Puede usar un iniciador que establece la ruta de clase correctamente. Entonces, tendrá mucha más flexibilidad para empaquetar sus JAR. Podrías ponerlos fácilmente en un directorio, que es mucho más limpio que crear un jar "ueber" bastardo ...

Uno de esos lanzadores es commons-launcher.

2

con la hormiga se podría hacer algo a lo largo de los siguientes:

  1. Grupo todas las dependencias juntos.
  2. Empaque un archivo JAR con su aplicación e incruste referencias a las dependencias en el archivo MANIFEST.MF con la dirección "Class-Path" dentro del contenedor. Eso debería eliminar la necesidad de construir el classpath en el lanzamiento.
  3. Agrupe todo junto como un archivo y distribúyalo. Debería ser suficiente ejecutar el jar directamente con "java -jar your.jar".

Para administrar sus dependencias, puede ir con Ivy.Al igual que Maven, es capaz de recuperar dependencias en el momento de la compilación desde cualquiera de los repositorios que configure, incluidos los repositorios Maven o su propio repositorio privado.

0

Estamos utilizando Maven 2 con m2eclipse plugin; funciona bastante bien El complemento tiene una vista de gráfico de dependencia, mostrará conflictos, etc.

Ahora, si desea empaquetar todas sus dependencias en el único contenedor, puede consultar Jar Jar Links (¡no es una broma!).

0

Muchas de sus preocupaciones desaparecen si convierte su JAR en ejecutable y agrega un manifiesto que incluye ClassPath. Por desgracia, tiene que ZIP el JAR y sus dependencias, pero se resuelven sus problemas CLASSPATH.

¿Qué tal crear un paquete OSGi? Todavía no lo he investigado, pero se supone que es lo siguiente para empaquetar aplicaciones Java. Se usa en servidores de aplicaciones como Spring's dm Server. Tal vez te pueda ayudar también.

0

En mi script de compilación ANT, genero las secuencias de comandos de inicio * .bat y * .sh con la lista de archivos JAR construidos dinámicamente en tiempo de compilación en función del contenido del directorio de compilación de la compilación.

Por ejemplo, para crear la lista de tarros con separadores apropiados:

<path id="jar-classpath"> 
    <fileset dir="${build.war.dir}/WEB-INF/lib"> 
     <include name="**/*.jar" /> 
    </fileset> 
</path> 

<pathconvert refid="jar-classpath" targetos="unix" property="exec.classpath.unix"> 
     <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/> 
</pathconvert> 

<pathconvert refid="jar-classpath" targetos="windows" property="exec.classpath.windows"> 
     <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/> 
</pathconvert> 

continuación, puede utilizar los ${exec.classpath.unix} y ${exec.classpath.windows} valores en las secuencias de comandos de invocación Java.

1

Todo esto amor de Maven y nadie menciona Ivy? ¡Oh querido!

Bueno, aquí está Ant Ivy y aquí está comparison to Maven2. Por favor, eche un vistazo también antes de ir con casi todo el mundo está sugiriendo.

0

El plugin maven-assembly-puede no ser la mejor opción. Usted debe echar un vistazo a la onejar-maven-plugin, tal como se describe aquí:

http://blog.jayway.com/2009/03/22/executable-jar-with-onejar-maven-plugin/

Se permite a todos sus tarros de dependencia se mantienen los frascos, y su código es en su propio frasco. Todos esos frascos se ponen en un frasco más grande, que se hace ejecutable.

0

También es posible usar Gradle y aquí es cómo puede hacerlo allí:

mainClassName = "my.App" 

task runnableJar(type: Jar, dependsOn: [':assemble']) { 
    from files(sourceSets.main.output.classesDir) 
    from files(sourceSets.main.output.resourcesDir) 
    from configurations.runtime.asFileTree.files.collect { zipTree(it) } 

    manifest { 
     attributes 'Main-Class': mainClassName 
    } 
} 
Cuestiones relacionadas