¿Es posible especificar un Java classpath
que incluya un archivo JAR contenido en otro archivo JAR?
¿Es posible especificar un Java classpath
que incluya un archivo JAR contenido en otro archivo JAR?
Respuestas:
Si está intentando crear un solo contenedor que contenga su aplicación y sus bibliotecas requeridas, hay dos maneras (que yo sepa) de hacerlo. El primero es One-Jar , que utiliza un cargador de clases especial para permitir el anidamiento de jarras. El segundo es UberJar , (o Shade ), que explota las bibliotecas incluidas y coloca todas las clases en el jar de nivel superior.
También debo mencionar que UberJar y Shade son complementos para Maven1 y Maven2 respectivamente. Como se menciona a continuación, también puede usar el complemento de ensamblaje (que en realidad es mucho más potente, pero mucho más difícil de configurar correctamente).
NO desea utilizar esas soluciones de "explosión de contenido JAR". Definitivamente hacen que sea más difícil ver cosas (ya que todo explota al mismo nivel). Además, podría haber conflictos de nombres (no debería suceder si las personas usan paquetes adecuados, pero no siempre se puede controlar esto).
La característica que desea es una de las 25 principales RFE de Sun : RFE 4648386 , que Sun, en su sabiduría infinita, ha designado como de baja prioridad. Solo podemos esperar que el Sol se despierte ...
Mientras tanto, la mejor solución que he encontrado (que deseo que Sun copie en el JDK) es usar el cargador de clases personalizado JarClassLoader .
activation.jar
)
Después de algunas investigaciones, he encontrado un método que no requiere Maven o cualquier extensión / programa de terceros.
Puede usar "Class-Path" en su archivo de manifiesto.
Por ejemplo:
Crear archivo de manifiesto MANIFEST.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
Compila todas tus clases y corre jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c
significa crear archivo
f
indica que desea especificar el archivo
v
es para entrada detallada
m
significa que pasaremos un archivo de manifiesto personalizado
Asegúrese de incluir lib en el paquete jar. Deberías poder ejecutar jar de la manera normal.
Residencia en: http://www.ibm.com/developerworks/library/j-5things6/
toda la otra información que necesita sobre la ruta de clase se encuentra aquí
custom_lib.jar
alejé, el frasco ya no se puede ejecutar :(
Use la etiqueta zipgroupfileset (usa los mismos atributos que una etiqueta de conjunto de archivos ); Descomprimirá todos los archivos en el directorio y los agregará a su nuevo archivo. Más información: http://ant.apache.org/manual/Tasks/zip.html
Esta es una forma muy útil de solucionar el problema de jar-in-a-jar: lo sé porque busqué en Google esta pregunta exacta de StackOverflow al intentar averiguar qué hacer. Si desea empaquetar un frasco o una carpeta de frascos en su único frasco construido con Ant, entonces olvídese de todo este classpath o complementos de terceros, todo lo que tiene que hacer es esto (en Ant):
<jar destfile="your.jar" basedir="java/dir">
...
<zipgroupfileset dir="dir/of/jars" />
</jar>
Si está construyendo con ant (estoy usando ant from eclipse), puede agregar los archivos jar adicionales diciendo a ant para agregarlos ... No necesariamente es el mejor método si tiene un proyecto mantenido por varias personas pero funciona para proyecto de una persona y es fácil.
por ejemplo, mi objetivo que estaba creando el archivo .jar era:
<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
<manifest>
<attribute name="Author" value="ntg"/>
................................
<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
</manifest>
</jar>
Acabo de agregar una línea para hacerlo:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
dónde
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
fue el directorio con los frascos externos. Y eso es...
Debe crear un cargador de clases personalizado para hacer esto o una biblioteca de terceros que lo admita. Su mejor opción es extraer el frasco del tiempo de ejecución y agregarlos al classpath (o tenerlos ya agregados al classpath).
Utilizo maven para mis compilaciones de java que tiene un complemento llamado complemento de ensamblaje de maven .
Hace lo que pides, pero como describen algunas de las otras sugerencias, básicamente explota todos los frascos dependientes y los recombina en un solo frasco
Si ha eclpise IDE, solo necesita exportar su JAR y elegir "Bibliotecas de paquetes requeridos en JAR generado". eclipse agregará automáticamente los JAR dependientes requeridos en el JAR generado, así como también generó un cargador de clases personalizado de eclipse que carga estos JAR automáticamente.
Estaba a punto de recomendar extraer todos los archivos en el mismo nivel, y luego hacer un tarro con el resultado, ya que el sistema de paquetes debería mantenerlos perfectamente separados. Esa sería la forma manual, supongo que las herramientas indicadas por Steve lo harán muy bien.
Winstone es bastante bueno http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Pero no para sitios complejos. Y eso es una pena porque todo lo que se necesita es incluir el complemento.
Bueno, hay una manera muy fácil si estás usando Eclipse.
Exporte su proyecto como un archivo Jar "Ejecutable" (haga clic con el botón derecho en la carpeta del proyecto desde Eclipse, seleccione "Exportar ..."). Cuando configure las opciones de exportación, asegúrese de seleccionar "Extraer las bibliotecas necesarias en el Jar generado". Recuerde, seleccione "Extraer ..." y no "Empaquetar bibliotecas requeridas ...".
Además : debe seleccionar una configuración de ejecución en su configuración de exportación. Por lo tanto, siempre puede crear un main () vacío en alguna clase y usarlo para su configuración de ejecución.
De todos modos, no se garantiza que funcione el 100% del tiempo, ya que notará un mensaje emergente que le indica que se asegure de verificar las licencias de los archivos Jar que está incluyendo y algo sobre no copiar archivos de firma. Sin embargo, he estado haciendo esto durante años y nunca he encontrado un problema.
La extracción en un Uber-dir funciona para mí, ya que todos deberíamos usar root: \ java y tener código de salidas en paquetes con versiones. Es decir, ca.tecreations-1.0.0. La firma está bien porque los frascos están intactos desde su ubicación descargada. Firmas de terceros intactas, extraer a c: \ java. Ahí está mi proyecto dir. ejecutar desde el lanzador para que Java -cp c: \ java Launcher