¿Cómo puedo crear un JAR ejecutable/ejecutable con dependencias usando Maven?

6 minutos de lectura

avatar de usuario de soemirno
soemirno

Quiero empaquetar mi proyecto en un único archivo 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?

  • Explique a qué objetivo del complemento de dependencia se refiere. No conozco ningún objetivo que haga lo que solicita la pregunta original: colocar todas las dependencias A) dentro del contenedor de autores a través del reempaquetado, o B) crear un contenedor ejecutable que tenga los demás en un classpath de MANIFEST.MF

    –Matthew McCullough

    11 de marzo de 2009 a las 15:11

  • Usted puede encontrar esto útil www.rationaljava.com/2015/02/…

    – Dan

    2 de febrero de 2015 a las 19:01

  • Consulte stackoverflow.com/questions/35217128/…

    – Thanga

    11 de septiembre de 2017 a las 8:18

Avatar de usuario de André Aronsen
André Aronsen

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 el classpath 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, utilice ${project.build.directory}/classes/lib como OutputDirectory para integrar todos los archivos JAR en el archivo JAR principal, pero luego deberá agregar un código de carga de clases personalizado para cargar los archivos JAR.

  • ¿Hay alguna manera de usar este método sin escribir cargadores de clases personalizados? Recibo “ClassNotFoundException”. Cuando comparé el complemento de ensamblaje, pensé que podría desempaquetar las dependencias usando maven-dependency-plugin. ¿Alguna recomendación?

    – gárbol

    13 de diciembre de 2021 a las 14:53

  • Esta extremadamente útil todavía

    – usuario1238097

    24 de agosto a las 0:09

  • ¿Hay alguna forma en que la fase del paquete agregue el script por lotes y bash al zip final para que el script pueda llamar a java -jar y solo me refiero al script?

    – SinaMobasheri

    6 sep a las 21:35

Avatar de usuario de Matthew McCullough
Mateo McCullough

Tomando la respuesta de IAdapter 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 para llamar explícitamente. Para que esto sea una parte integral de su compilación, agregue este complemento a su pom.xml y atarlo a la package evento del ciclo de vida. Sin embargo, un problema es que debe llamar al assembly:single objetivo si coloca esto en su pom.xml, mientras que llamaría ‘ensamblaje: ensamblaje’ si lo ejecuta manualmente desde la línea de comando.

<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>

  • en mi caso, maven-assembly-plugin fue suficiente. Gracias

    – Kampaii

    8 de septiembre a las 6:31

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Utilizar el maven-shade-complemento para empaquetar todas las dependencias en un archivo über-JAR. También se puede utilizar para crear un archivo 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.

Vea el ejemplo a continuación:

<plugins>
    <!-- This plugin provides the capability to package
         the artifact in an über-JAR file, 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 JAR files-->
                        <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>

  • en mi caso, maven-assembly-plugin fue suficiente. Gracias

    – Kampaii

    8 de septiembre a las 6:31

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Puede usar el complemento maven-shade para crear un archivo über JAR como el siguiente:

<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>

¿Ha sido útil esta solución?