java - que - maven no descarga dependencias
Incluyendo dependencias en un frasco con Maven. (13)
Ahí está el complemento de la cortina de sombra . Se puede usar para empaquetar y renombrar dependencias (para omitir problemas de dependencia en la ruta de clase).
¿Hay una manera de forzar a maven (2.0.9) a incluir todas las dependencias en un solo archivo jar?
Tengo un proyecto que se construye en un solo archivo jar. Quiero que las clases de dependencias se copien también en el jar.
Actualización: Sé que no puedo simplemente incluir un archivo jar en un archivo jar. Estoy buscando una manera de descomprimir los archivos jar especificados como dependencias y empaquetar los archivos de clase en mi archivo jar.
Con Maven 2, la forma correcta de hacerlo es usar el Complemento de ensamblaje de Maven2 que tiene un archivo descriptor predefinido para este propósito y que podría usar en la línea de comandos:
mvn assembly:assembly -DdescriptorId=jar-with-dependencies
Si desea hacer este ejecutable jar, simplemente agregue la clase principal que se ejecutará a la configuración del complemento:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>my.package.to.my.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Si desea crear ese ensamblaje como parte del proceso de compilación normal, debe vincular el objetivo single o single directory-single (el objetivo del assembly
SOLAMENTE debe ejecutarse desde la línea de comandos) a una fase del ciclo de vida (el package
tiene sentido), algo así como esta:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-my-bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
...
</configuration>
</execution>
</executions>
</plugin>
Adapte el elemento de configuration
para que se adapte a sus necesidades (por ejemplo, con el material del manifiesto tal como se habla).
Dejando a un lado a Maven, puedes poner las bibliotecas JAR dentro del tarro principal, pero necesitarás usar tu propio cargador de clases.
Revisa este proyecto: texto de enlace de One-JAR
Esta publicación puede ser un poco antigua, pero también tuve el mismo problema recientemente. La primera solución propuesta por John Stauffer es buena, pero tuve algunos problemas mientras trabajo esta primavera. Los frascos de dependencia de Spring que utilizo tienen algunos archivos de propiedades y declaración de esquemas xml que comparten las mismas rutas y nombres. Aunque estos archivos jar provienen de las mismas versiones, el archivo jar con dependencias maven-goal estaba sobrescribiendo el archivo de tesis con el último archivo encontrado.
Al final, la aplicación no pudo iniciarse ya que los archivos de primavera no pudieron encontrar los archivos de propiedades correctos. En este caso la solución propuesta por Rop ha solucionado mi problema.
También desde entonces, el proyecto de arranque de primavera ahora existe. Tiene una manera muy buena de manejar este problema al proporcionar un objetivo experto que sobrecarga el objetivo del paquete y proporciona su propio cargador de clases. Ver la guía de referencia de botas de primavera
Gracias, agregué el siguiente fragmento de código en el archivo POM.xml y el problema de Mp se resolvió y se creó un archivo de archivos de grasa que incluye todos los archivos dependientes.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
Mi solución definitiva en Eclipse Luna y m2eclipse: Custom Classloader (descargar y agregar a su proyecto, solo 5 clases): http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/plain/org.eclipse.jdt.ui/jar%20in%20jar%20loader/org/eclipse/jdt/internal/jarinjarloader/ ; este cargador de clases es el mejor de un cargador de clases de un solo tarro y muy rápido;
<project.mainClass>org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>
Editar en JIJConstants "Rsrc-Class-Path" a "Class-Path"
dependencia mvn limpia: paquete de dependencias de copia
se crea un jar con dependencias en la carpeta lib con un cargador de clases delgado
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
<targetPath>META-INF/</targetPath>
</resource>
<resource>
<directory>${project.build.directory}/dependency/</directory>
<includes>
<include>*.jar</include>
</includes>
<targetPath>lib/</targetPath>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>${project.mainClass}</mainClass>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Rsrc-Main-Class>${project.realMainClass} </Rsrc-Main-Class>
<Class-Path>./</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Puede hacer esto usando el plugin de ensamblaje de maven con el descriptor "jar-with-dependencies". Aquí está el fragmento relevante de uno de nuestros pom.xml que hace esto:
<build>
<plugins>
<!-- any other plugins -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
Puedes usar el jar recién creado usando una etiqueta <classifier>
.
<dependencies>
<dependency>
<groupId>your.group.id</groupId>
<artifactId>your.artifact.id</artifactId>
<version>1.0</version>
<type>jar</type>
<classifier>jar-with-dependencies</classifier>
</dependency>
</dependencies>
Si a usted (como a mí) no le gusta especialmente el enfoque de tarro con dependencias descrito anteriormente, la solución de Maven que prefiero es simplemente construir un proyecto WAR, incluso si solo está construyendo una aplicación Java independiente:
Haga un proyecto jar de maven normal, que construirá su archivo jar (sin las dependencias).
Además, configure un proyecto de guerra maven (con solo un archivo vacío src / main / webapp / WEB-INF / web.xml , que evitará una advertencia / error en la construcción maven), que solo tiene su proyecto-jar como una dependencia, y haga que su proyecto de jarra sea un
<module>
bajo su proyecto de guerra. (Este proyecto de guerra es solo un simple truco para envolver todas sus dependencias de archivos jar en un archivo zip).Construye el proyecto de guerra para producir el archivo de guerra.
En el paso de implementación, simplemente cambie el nombre de su archivo .war a * .zip y descomprímalo.
Ahora debería tener un directorio lib (que puede mover a donde lo desee) con su archivo jar y todas las dependencias que necesita para ejecutar su aplicación:
java -cp ''path/lib/*'' MainClass
(El comodín en classpath funciona en Java-6 o superior)
Creo que esto es tanto más fácil de configurar en maven (no es necesario que juegues con el plugin de ensamblaje) y también te da una vista más clara de la estructura de la aplicación (verás los números de versión de todos los archivos dependientes a simple vista, y evitar la obstrucción de todo en un solo archivo jar).
Si desea hacer un archivo jar ejecutable, ellos también necesitan establecer la clase principal. Así que la configuración completa debería ser.
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- ... -->
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
Echa un vistazo a esta respuesta:
Estoy creando un instalador que se ejecuta como un archivo JAR de Java y necesita descomprimir los archivos WAR y JAR en los lugares apropiados en el directorio de instalación. El complemento de dependencia se puede utilizar en la fase del paquete con el objetivo de copia y descargará cualquier archivo en el repositorio de Maven (incluidos los archivos WAR) y los escribirá donde sea que los necesite. Cambié el directorio de salida a $ {project.build.directory} / classes y luego el resultado final es que la tarea JAR normal incluye mis archivos muy bien. Luego puedo extraerlos y escribirlos en el directorio de instalación.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>getWar</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>the.group.I.use</groupId>
<artifactId>MyServerServer</artifactId>
<version>${env.JAVA_SERVER_REL_VER}</version>
<type>war</type>
<destFileName>myWar.war</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
http://fiji.sc/Uber-JAR proporciona una excelente explicación de las alternativas:
Hay tres métodos comunes para construir un uber-JAR:
- Sin sombra. Desempaquete todos los archivos JAR, luego vuelva a empaquetarlos en un solo JAR.
- Pro: Funciona con el cargador de clases predeterminado de Java.
- Con: Los archivos presentes en varios archivos JAR con la misma ruta (por ejemplo, META-INF / services / javax.script.ScriptEngineFactory) se sobrescribirán entre sí, lo que dará como resultado un comportamiento defectuoso.
- Herramientas: Maven Assembly Plugin, Classworlds Uberjar
- Sombreado Igual que sin sombrear, pero renombrar (es decir, "sombrear") todos los paquetes de todas las dependencias.
- Pro: Funciona con el cargador de clases predeterminado de Java. Evita algunos (no todos) choques de versiones de dependencia.
- Con: Los archivos presentes en varios archivos JAR con la misma ruta (por ejemplo, META-INF / services / javax.script.ScriptEngineFactory) se sobrescribirán entre sí, lo que dará como resultado un comportamiento defectuoso.
- Herramientas: Maven Shade Plugin
- JAR DE JARS. El archivo JAR final contiene los otros archivos JAR incrustados dentro.
- Pro: Evita los choques de versiones de dependencia. Todos los archivos de recursos se conservan.
- Contras: necesita agrupar un cargador de clases especial "bootstrap" para permitir que Java cargue clases desde los archivos JAR envueltos. La depuración de problemas del cargador de clases se vuelve más compleja.
- Herramientas: Eclipse JAR File Exporter, One-JAR.
<!-- Method 1 -->
<!-- Copy dependency libraries jar files to a separated LIB folder -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<excludeTransitive>false</excludeTransitive>
<stripVersion>false</stripVersion>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Add LIB folder to classPath -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Method 2 -->
<!-- Package all libraries classes into one runnable jar -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>