java - plugin - maven generar jar con dependencias
¿Cómo puedo crear un JAR ejecutable con dependencias usando Maven? (30)
¿Problema con localizar el archivo de ensamblaje compartido con maven-assembly-plugin-2.2.1?
Intente usar el parámetro de configuración descriptorId en lugar de los descriptores / descriptor o los parámetros descriptorRefs / descriptorRef.
Ninguno de los dos hace lo que necesita: busque el archivo en classpath. Por supuesto, necesita agregar el paquete donde reside el ensamblaje compartido en el classpath de maven-assembly-plugin (ver más abajo). Si está utilizando Maven 2.x (no Maven 3.x), es posible que necesite agregar esta dependencia en pom.xml principal superior en la sección de administración de plugin.
Vea this para más detalles.
Clase: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
Ejemplo:
<!-- Use the assembly plugin to create a zip file of all our dependencies. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorId>assembly-zip-for-wid</descriptorId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>cz.ness.ct.ip.assemblies</groupId>
<artifactId>TEST_SharedAssemblyDescriptor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
Quiero empaquetar mi proyecto en un solo archivo JAR ejecutable para su distribución.
¿Cómo puedo hacer un paquete de proyecto Maven todos los JAR de dependencia en mi JAR de salida?
Algo que me ha funcionado fue:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>SimpleKeyLogger</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Tuve un caso extraordinario porque mi dependencia era del sistema uno:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
He cambiado el código provisto por @ user189057 con cambios: 1) maven-dependency-plugin se ejecuta en la fase 2 de "prepare-package") Estoy extrayendo clases desempaquetadas directamente a "target / classes"
Aquí hay un plugin ejecutable para Maven que usamos en Credit Karma. Crea un tarro de tarros con un cargador de clases capaz de cargar clases desde tarros anidados. Esto le permite tener el mismo classpath en dev y prod y aún así mantener todas las clases en un solo archivo jar firmado.
https://github.com/creditkarma/maven-exec-jar-plugin
Y aquí hay una publicación de blog con detalles sobre el complemento y por qué lo hicimos: https://engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven/
Comparé los complementos de árbol mencionados en este post. Generé 2 tarros y un directorio con todos los tarros. Comparé los resultados y definitivamente el plug-in de maven-shade es el mejor. Mi desafío fue que tengo múltiples recursos de primavera que debían fusionarse, así como jax-rs y servicios JDBC. Todos se combinaron correctamente con el complemento de color en comparación con el complemento de montaje de maven. En cuyo caso, la primavera fallará a menos que los copie en su propia carpeta de recursos y los combine manualmente una vez. Ambos complementos generan el árbol de dependencias correcto. Tuve varios ámbitos como prueba, proporcionar, compilar, etc. La prueba y la información proporcionada fueron omitidas por ambos complementos. Ambos produjeron el mismo manifiesto, pero pude consolidar las licencias con el complemento de sombra usando su transformador. Por supuesto, con el complemento de dependencia de maven no tiene esos problemas porque los archivos no se extraen. Pero como algunos otros han señalado, debe llevar uno o más archivos adicionales para que funcione correctamente. Aquí hay un recorte del pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>compile</includeScope>
<excludeTransitive>true</excludeTransitive>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Debería ser así:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
El desempaque debe estar en la fase de generación de recursos porque, si está en la fase de paquete, no se incluirá como recursos. Prueba el paquete limpio y lo verás.
Durante mucho tiempo usé el plugin de ensamblaje de Maven , pero no pude encontrar una solución al problema con "already added, skipping"
. Ahora, estoy usando otro plugin - onejar-maven-plugin . Ejemplo a continuación ( mvn package
build jar):
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<configuration>
<mainClass>com.company.MainClass</mainClass>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Necesitas agregar un repositorio para ese complemento:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
El plugin de montaje de maven me funcionó muy bien. Pasé horas con el complemento de dependencia de Maven y no pude hacer que funcionara. La razón principal fue que tuve que definir explícitamente en la sección de configuración los elementos de artefactos que deberían incluirse tal como se describe en la documentation . Hay un ejemplo para los casos en los que desea usarlo como: mvn dependency:copy
, donde no se incluye ningún artifactItems pero no funciona.
Esta es la mejor manera que encontré:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.myDomain.etc.MainClassName</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Con esta configuración, todas las dependencias se ubicarán en /dependency-jars
. Mi aplicación no tiene clase Main
, solo contexto, pero una de mis dependencias tiene una clase Main
( com.myDomain.etc.MainClassName
) que inicia el servidor JMX y recibe un parámetro de start
o stop
. Así que con esto pude iniciar mi aplicación así:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Espero les sea de utilidad a todos.
Esto también podría ser una opción. Podrás construir tu archivo jar.
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>WordListDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Hice un blog sobre algunas maneras diferentes de hacer esto.
Ver Frasco ejecutable con Apache Maven (WordPress)
o executable-jar-with-maven-example (GitHub)
Notas
Estos pros y contras son proporcionados por Stephan .
Para el despliegue manual
- Pros
- Contras
- Las dependencias están fuera de la jarra final.
Copiar dependencias a un directorio específico
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Haz que el ejecutable Jar y Classpath sean conscientes
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
<mainClass>${fully.qualified.main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
En este punto, el jar
es realmente ejecutable con elementos de classpath externos.
$ java -jar target/${project.build.finalName}.jar
Hacer archivos desplegables
El archivo jar
solo es ejecutable con el directorio sibling ...lib/
. Necesitamos hacer archivos para desplegar con el directorio y su contenido.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>antrun-archive</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
<property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
<property name="tar.destfile" value="${final.name}.tar"/>
<zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
<tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
<gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
<bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
</target>
</configuration>
</execution>
</executions>
</plugin>
Ahora tiene target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
cada uno de los cuales contiene el jar
y lib/*
.
Apache Maven Assembly Plugin
- Pros
- Contras
- No es compatible con la reubicación de clases (use el complemento maven-shade-plug si se necesita la reubicación de clases)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>${fully.qualified.main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Tienes target/${project.bulid.finalName}-jar-with-dependencies.jar
.
Apache Maven Shade Plugin
- Pros
- Contras
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${fully.qualified.main.class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Tienes target/${project.build.finalName}-shaded.jar
.
plugin de Onejar-Maven
- Pros
- Contras
- No apoyado activamente desde 2012.
<plugin>
<!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>${fully.qualified.main.class}</mainClass>
<attachToBuild>true</attachToBuild>
<!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
<!--classifier>onejar</classifier-->
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Spring Boot Maven Plugin
- Pros
- Contras
- Añadir posibles clases relacionadas con Spring y Spring Boot innecesarias.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>${fully.qualified.main.class}</mainClass>
</configuration>
</execution>
</executions>
</plugin>
Tienes target/${project.bulid.finalName}-spring-boot.jar
.
Intenté la respuesta más votada aquí, y pude obtener el tarro ejecutable. Pero el programa no se ejecutó correctamente. No sé cuál fue la razón. Cuando intento ejecutar desde Eclipse
, obtengo un resultado diferente, pero cuando ejecuto el jar desde la línea de comandos obtengo un resultado diferente (se bloquea con un error de tiempo de ejecución específico del programa).
Tenía un requisito similar al OP, solo que tenía demasiadas dependencias (Maven) para mi proyecto. Afortunadamente, la única solución que funcionó para mí fue usar Eclipse
. Muy simple y muy sencillo. Esta no es una solución para el OP, pero es una solución para alguien que tiene un requisito similar pero con muchas dependencias de Maven.
1) Simplemente haga clic derecho en la carpeta de su proyecto (en Eclipse) y seleccione Export
2) Luego seleccione Java
-> Runnable Jar
3) Se le pedirá que elija la ubicación del archivo jar
4) Finalmente, seleccione la clase que tiene el método principal que desea ejecutar y elija las Package dependencies with the Jar file
y haga clic en Finish
Ken Liu tiene razón en mi opinión. El complemento de dependencia de Maven le permite expandir todas las dependencias, que luego puede tratar como recursos. Esto te permite incluirlos en el artefacto principal . El uso del complemento de ensamblaje crea un artefacto secundario que puede ser difícil de modificar; en mi caso, quería agregar entradas de manifiesto personalizadas. Mi pom terminó como
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
<resources>
<resource>
<directory>${basedir}/target/dependency</directory>
<targetPath>/</targetPath>
</resource>
</resources>
</build>
...
</project>
No responderé directamente a la pregunta, ya que otros ya lo han hecho antes, pero realmente me pregunto si es una buena idea integrar todas las dependencias en el propio frasco del proyecto.
Veo el punto (facilidad de implementación / uso) pero depende del caso de uso de su proyecto (y puede haber alternativas (ver más abajo)).
Si lo usa completamente independiente, ¿por qué no?
Pero si usa su proyecto en otros contextos (como en una aplicación web, o si se coloca en una carpeta donde se encuentran otros frascos), es posible que tenga duplicados de jarra en su ruta de clase (las que están en la carpeta, la de las jarras). Tal vez no sea una oferta de oferta, pero por lo general evito esto.
Una buena alternativa:
- implemente su aplicación como .zip / .war: el archivo contiene el archivo de su proyecto y todos los archivos dependientes;
- use un mecanismo dinámico de carga de clases (vea Spring, o puede hacerlo fácilmente usted mismo) para tener un solo punto de entrada de su proyecto (una clase única para comenzar - vea el mecanismo de manifiesto en otra respuesta), que se agregará (dinámicamente) a la classpath actual todos los otros tarros necesarios.
Así, con al final solo un manifiesto y un "principal dinámico de carga de clases especial", puede comenzar su proyecto con:
java -jar ProjectMainJar.jar com..projectName.MainDynamicClassLoaderClass
Otra opción si realmente desea volver a empaquetar los otros contenidos JAR dentro de su único JAR resultante es el complemento de Ensamblaje de Maven . Desempaqueta y luego vuelve a empaquetar todo en un directorio a través de <unpack>true</unpack>
. Entonces tendrías un segundo pase que lo convirtió en un JAR masivo.
onejar-maven-plugin . Esto realiza las acciones de reenvasado anteriores en un solo paso.
Para cualquiera que busque opciones para excluir dependencias específicas del uber-jar, esta es una solución que funcionó para mí:
<project...>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.6.1</version>
<scope>provided</scope> <=============
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Entonces, no es una configuración de mvn-assembly-plugin sino una propiedad de la dependencia.
Para resolver este problema, usaremos el Complemento de ensamblaje de Maven que creará el JAR junto con sus JAR de dependencia en un solo archivo JAR ejecutable. Solo agregue la siguiente configuración de plugin en su archivo pom.xml.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.your.package.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Después de hacer esto, no olvide ejecutar la herramienta MAVEN con este comando mvn clean compile assembly: single
Podrías combinar el maven-shade-plugin
maven-jar-plugin
y el maven-shade-plugin
maven-jar-plugin
.
- El
maven-shade-plugin
in demaven-shade-plugin
empaqueta sus clases y todas las dependencias en un solo archivo jar. - Configure el
maven-jar-plugin
para especificar la clase principal de su archivo ejecutable (consulte Configurar el Classpath , capítulo "Hacer ejecutable el archivo Jar").
Ejemplo de configuración de POM para maven-jar-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Finalmente crea el jar ejecutable invocando:
mvn clean package shade:shade
Puede usar el complemento de dependencia de maven, pero la pregunta era cómo crear un JAR ejecutable. Para hacer eso se requiere la siguiente modificación de la respuesta de Matthew Franglen (por cierto, usar el complemento de dependencia toma más tiempo para construirse cuando se inicia desde un objetivo limpio):
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/target/dependency</directory>
</resource>
</resources>
</build>
Puede usar el complemento de dependencia para generar todas las dependencias en un directorio separado antes de la fase del paquete y luego incluirlo en la ruta de clase del manifiesto:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>theMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Alternativamente, use ${project.build.directory}/classes/lib
como OutputDirectory para integrar todos los archivos jar en el jar principal, pero luego tendrá que agregar un código de carga de clases personalizado para cargar los archivos jar.
Puedes agregar lo siguiente a tu pom.xml :
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.package.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.mycompany.package.MainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Luego, debe cambiar a través del directorio, donde se encuentra el archivo pom.xml. Luego tiene que ejecutar mvn assembly: solo se construirá el archivo JAR ejecutable con dependencias. Puede verificarlo al cambiar al directorio de salida (destino) con cd ./target y al iniciar su jar con un comando similar a java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
He probado esto con Apache Maven 3.0.3 .
Puedes usar el plugin de maven-shade para construir un frasco de uber como el de abajo
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Repasé cada una de estas respuestas buscando hacer un frasco ejecutable grueso que contenga todas las dependencias y ninguna de ellas funcionó correctamente. La respuesta es el complemento de sombra, es muy fácil y directo.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>path.to.MainClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Tenga en cuenta que sus dependencias deben tener un alcance de compilación o tiempo de ejecución para que esto funcione correctamente.
Si quieres si desde la propia línea de comandos. Simplemente ejecute el siguiente comando desde la ruta del proyecto
montaje mvn: montaje
También puede usar este complemento, es bastante bueno y lo uso para empaquetar mis archivos jar http://sonatype.github.io/jarjar-maven-plugin/
Tomando la respuesta de Sin contestar y reformateando, tenemos:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
A continuación, recomendaría hacer de esto una parte natural de su construcción, en lugar de algo para llamar explícitamente. Para hacer de esto una parte integral de su compilación, agregue este complemento a su pom.xml
y pom.xml
al evento del ciclo de vida del package
. Sin embargo, un problema es que debe llamar al assembly:single
objetivo assembly:single
si coloca esto en su pom.xml, mientras que llamaría ''ensamblaje: ensamblaje'' si lo ejecuta manualmente desde la línea de comandos.
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</plugins>
[...]
</build>
</project>
Use el complemento onejar para crearlo como un archivo jar ejecutable que contiene todos los archivos jar de dependencia en él. Eso resolvió mi problema que era similar a esto. Cuando se usó el complemento de ensamblaje, desempaquetó todos los archivos jar de dependencia en la carpeta de origen y los volvió a empaquetar como un archivo jar, había sobreescrito todas las implementaciones similares que tenía dentro de mi código que tenían los mismos nombres de clase. onejar es una solución fácil aquí.
Use el plugin de maven-shade para empaquetar todas las dependencias en un uber-jar. También se puede usar para construir un jar ejecutable especificando la clase principal. Después de intentar usar maven-assembly y maven-jar, descubrí que este complemento se adaptaba mejor a mis necesidades.
Encontré este complemento particularmente útil ya que combina el contenido de archivos específicos en lugar de sobrescribirlos. Esto es necesario cuando hay archivos de recursos que tienen el mismo nombre en los archivos jar y el complemento intenta empaquetar todos los archivos de recursos
Ver ejemplo abajo
<plugins>
<!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<!-- signed jars-->
<excludes>
<exclude>bouncycastle:bcprov-jdk15</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!-- Main class -->
<mainClass>com.main.MyMainClass</mainClass>
</transformer>
<!-- Use resource transformers to prevent file overwrites -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>properties.properties</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>applicationContext.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/cxf/cxf.extension</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/bus-extensions.xml</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Añadir a pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
y
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Eso es. El próximo paquete mvn también creará un frasco de grasa adicional, incluidos todos los frascos de dependencia.
Ya hay millones de respuestas, quería agregar que no es necesario <mainClass>
si no necesita agregar entryPoint a su aplicación. Por ejemplo, las API pueden no tener necesariamente un main
método.
configuración de plugin de maven
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
construir
mvn clean compile assembly:single
verificar
ll target/
total 35100
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 maven-status/
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
y lo ejecutas con
mvn clean compile assembly:single
El objetivo de compilación se debe agregar antes del ensamblaje: no se incluye el código de su propio proyecto.
Ver más detalles en los comentarios.
Comúnmente, este objetivo está vinculado a una fase de construcción para ejecutarse automáticamente. Esto garantiza que el JAR se mvn install
al ejecutar la mvn install
o al realizar una implementación / lanzamiento.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>