Quiero empaquetar mi proyecto en un solo JAR ejecutable para su distribución.
¿Cómo puedo hacer que un proyecto de Maven empaquete todos los JAR de dependencia en mi JAR de salida?
Quiero empaquetar mi proyecto en un solo JAR ejecutable para su distribución.
¿Cómo puedo hacer que un proyecto de Maven empaquete todos los JAR de dependencia en mi JAR de salida?
Respuestas:
<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 debe agregarse antes del ensamblaje: individual o de lo contrario, el código de su propio proyecto no está incluido.
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 construya al ejecutar mvn install
o 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>
mvn clean compile assembly:single
.
<appendAssemblyId>false</appendAssemblyId>
en el configuration
para evitar el molesto sufijo "-jar-with-dependencies" en el nombre
compile
y estás jodido.
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 usar ${project.build.directory}/classes/lib
como OutputDirectory para integrar todos los archivos jar en el jar principal, pero luego deberá agregar un código de carga de clase personalizado para cargar los jar.
${project.build.directory}/classes/lib
como outputDirectory
para tener un .jar principal con todas las dependencias dentro, pero: ¿cómo agregar un código de carga de clase personalizado para cargar estos tarros? Necesito hacer ejecución de obras como: java -jar main-jar-with-deps.jar
. Es posible ?
Escribí en el blog sobre algunas formas diferentes de hacer esto.
Ver Jar ejecutable con Apache Maven (WordPress)
o ejecutable-jar-with-maven-example (GitHub)
Esos pros y contras son proporcionados por Stephan .
<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>
<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
El jar
archivo solo es ejecutable con el ...lib/
directorio hermano . Necesitamos crear archivos para implementar 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)
cuál contiene el jar
y lib/*
.
<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>
Usted tiene target/${project.bulid.finalName}-jar-with-dependencies.jar
.
<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>
Usted tiene target/${project.build.finalName}-shaded.jar
.
<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>
<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>
Usted tiene target/${project.bulid.finalName}-spring-boot.jar
.
Tomando la respuesta de Unnsresponded y reformateándola, 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 compilación, en lugar de algo a lo que llamar explícitamente. Para hacer de esto una parte integral de su compilación, agregue este complemento a su pom.xml
y vincúlelo al package
evento del ciclo de vida. Sin embargo, un problema es que debes llamar al assembly:single
objetivo si lo pones en tu pom.xml, mientras que llamarías 'ensamblaje: ensamblaje' si lo ejecutas 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 maven-shade-plugin 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 frascos y el complemento intenta empaquetar todos los archivos de recursos
Ver ejemplo a continuación
<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>
Durante mucho tiempo usé el complemento de ensamblaje maven , pero no pude encontrar una solución al problema "already added, skipping"
. Ahora, estoy usando otro complemento: 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>
Debe agregar el 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>
Puede usar maven-dependency-plugin, pero la pregunta era cómo crear un JAR ejecutable. Hacer eso requiere la siguiente alteración a la respuesta de Matthew Franglen (por cierto, usar el complemento de dependencia toma más tiempo para construir cuando se comienza 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 maven-shade para construir un súper jar como se muestra a continuación
<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>
Otra opción si realmente desea volver a empaquetar los otros contenidos de JAR dentro de su JAR resultante único es el complemento Maven Assembly . Descomprime 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.
Otra opción es el complemento OneJar . Esto realiza las acciones de reempaquetado anteriores en un solo paso.
Puede agregar lo siguiente a su 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 de la consola al directorio, donde se encuentra el pom.xml. Luego debe ejecutar mvn assembly: single y luego su archivo JAR ejecutable con dependencias se construirá con suerte. Puede verificarlo al cambiar al directorio de salida (destino) con cd ./target e iniciar su jar con un comando similar a java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
Probé esto con Apache Maven 3.0.3 .
Revisé cada una de estas respuestas buscando hacer un jar ejecutable que contenga todas las dependencias y ninguna 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.
plugin
elemento entra pom.xml
debajo build/plugins
.
Podrías combinar el maven-shade-plugin
y maven-jar-plugin
.
maven-shade-plugin
paquetes de sus clases y todas las dependencias en un solo archivo JAR.maven-jar-plugin
para especificar la clase principal de su jar ejecutable (consulte Configurar el Classpath , capítulo "Hacer ejecutable el 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 cree el jar ejecutable invocando:
mvn clean package shade:shade
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 le 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>
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 desempaquetado 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.
¿Problema con la ubicación del archivo de ensamblaje compartido con maven-assembly-plugin-2.2.1?
Intente usar el parámetro de configuración descriptorId en lugar de los parámetros descriptors / descriptor o descriptorRefs / descriptorRef.
Ninguno de ellos hace lo que necesita: busque el archivo en classpath. Por supuesto, debe agregar el paquete donde reside el ensamblado compartido en el classpath de maven-assembly-plugin (ver a continuación). Si está utilizando Maven 2.x (no Maven 3.x), es posible que necesite agregar esta dependencia en pom.xml padre superior en la sección pluginManagement.
Vea esto 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>
Para resolver este problema, utilizaremos Maven Assembly Plugin que creará el JAR junto con sus JAR de dependencia en un solo archivo JAR ejecutable. Simplemente agregue la configuración del complemento a continuación 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
No responderé directamente a la pregunta ya que otros ya lo han hecho antes, pero realmente me pregunto si es una buena idea incrustar todas las dependencias en el propio jar 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 se deja caer en una carpeta donde se encuentran otros frascos), es posible que tenga duplicados de jar en su classpath (los que están en la carpeta, el que está en los frascos). Tal vez no sea un acuerdo de oferta, pero generalmente evito esto.
Una buena alternativa
De esta manera, al final solo con un manifiesto y un "cargador principal de clases dinámico especial", puede comenzar su proyecto con:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Para crear un JAR ejecutable desde la línea de comandos, simplemente ejecute el siguiente comando desde la ruta del proyecto:
mvn assembly:assembly
pom.xml
caso contrario Error reading assemblies: No assembly descriptors found.
. Eso es lo que me pasa de todos modos.
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 Main
clase, solo contextuales, pero una de mis dependencias tiene una Main
clase ( com.myDomain.etc.MainClassName
) que inicia el servidor JMX y recibe start
un stop
parámetro o un parámetro. Entonces con esto pude iniciar mi aplicación así:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Espero que sea útil para todos ustedes.
Comparé los complementos de árbol mencionados en esta publicación. Genere 2 frascos y un directorio con todos los frascos. Comparé los resultados y definitivamente el complemento maven-shade-plugin es el mejor. Mi desafío era que tenía múltiples recursos de primavera que debían fusionarse, así como jax-rs y servicios JDBC. Todos se fusionaron correctamente con el complemento de sombra en comparación con el complemento de ensamblaje maven. En ese caso, el resorte fallará a menos que los copie en su propia carpeta de recursos y los fusione manualmente una vez. Ambos complementos generan el árbol de dependencia correcto. Tuve múltiples ámbitos como prueba, proporcionar, compilar, etc. La prueba y la provista fueron omitidas por ambos complementos. Ambos produjeron el mismo manifiesto, pero pude consolidar las licencias con el complemento de sombra utilizando su transformador. Con el complemento de dependencia de Maven, por supuesto, no lo haces No tengo esos problemas porque los frascos 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 fragmento de 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>
Algo que me funcionó 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 el sistema uno:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
He cambiado el código proporcionado por @ user189057 con los cambios: 1) maven-dependency-plugin se ejecuta en la fase 2 "prepare-package") Estoy extrayendo las clases desempaquetadas directamente a "target / classes"
Intenté la respuesta más votada aquí, y pude obtener el jar ejecutable. Pero el programa no se ejecutó correctamente. No sé cuál fue la razón. Cuando trato de huir deEclipse
, 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 porque tenía demasiadas dependencias (Maven) para mi proyecto. Afortunadamente, la única solución que funcionó para mí fue usarla Eclipse
. Muy simple y muy directo. 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 Package dependencies with the Jar file
y haga clicFinish
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>
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>
Por lo tanto, no es una configuración de mvn-assembly-plugin sino una propiedad de la dependencia.
Ya hay millones de respuestas, quería agregar que no necesita <mainClass>
si no necesita agregar entryPoint a su aplicación. Por ejemplo, las API pueden no tener necesariamente un main
método.
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean compile assembly:single
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/
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 siguiente paquete mvn también creará un tarro gordo adicionalmente, incluyendo todos los tarros de dependencia.
El complemento de ensamblaje maven funcionó muy bien para mí. Pasé horas con el complemento de dependencia de maven y no pude hacerlo funcionar. La razón principal fue que tuve que definir en la sección de configuración explícitamente los elementos de artefactos que deberían incluirse tal como se describe en la documentación . Hay un ejemplo para los casos en que desea usarlo como: mvn dependency:copy
donde no se incluyen ningún objeto de artefacto pero no funciona.
Esta publicación de blog muestra otro enfoque con la combinación de los complementos maven-jar y maven-assembly. Con la configuración de ensamblado xml de la publicación del blog, también se puede controlar si las dependencias se expandirán o solo se recopilarán en una carpeta y se hará referencia a ellas mediante una entrada de classpath en el manifiesto:
La solución ideal es incluir los archivos jar en una carpeta lib y el archivo manifest.mf del archivo jar principal incluye todos los archivos jar en classpath.
Y exactamente ese se describe aquí: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Bien, entonces esta es mi solución. Sé que no está usando el archivo pom.xml. Pero tuve el problema de que mi programa se compilara y ejecutara en Netbeans pero fallaba cuando probé Java -jar MyJarFile.jar. Ahora, no entiendo completamente a Maven y creo que por eso estaba teniendo problemas para que Netbeans 8.0.2 incluyera mi archivo jar en una biblioteca para ponerlos en un archivo jar. Estaba pensando en cómo solía usar archivos jar sin Maven en Eclipse.
Es Maven que puede compilar todas las dependencias y complementos. No Netbeans. (Si puede obtener Netbeans y poder usar java .jar para hacer esto, dígame cómo (^. ^) V)
[Resuelto - para Linux] abriendo una terminal.
Entonces
cd /MyRootDirectoryForMyProject
próximo
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
próximo
mvn install
Esto creará un archivo jar en el directorio de destino.
MyJarFile-1.0-jar-with-dependencies.jar
Ahora
cd target
(Es posible que tenga que ejecutar: chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)
Y finalmente
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Por favor mira
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Publicaré esta solución en un par de otras páginas con un problema similar. Espero poder salvar a alguien de una semana de frustración.