Incluir dependencias en un jar con Maven


¿Hay alguna manera de forzar a maven(2.0.9) a incluir todas las dependencias en un solo archivo jar?

Tengo un proyecto de las compilaciones en un solo archivo jar. Quiero que las clases de dependencias se copien en el jar también.

Update: Sé que no puedo incluir un archivo jar en un archivo jar. Estoy buscando una manera de descomprimir los jars que se especifican como dependencias, y empaquetar los archivos de clase en mi jar.

Author: James McMahon, 2009-11-13

13 answers

Puede hacer esto usando el plugin maven-assembly 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>
 381
Author: John Stauffer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-23 09:54:33

Con Maven 2, la forma correcta de hacer esto es usar el Complemento Maven2 Assembly que tiene un archivo descriptor predefinido para este propósito y que solo puede usar en la línea de comandos:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

Si desea que este jar sea ejecutable, simplemente agregue la clase principal a 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 ensamblado como parte del proceso de compilación normal, debe enlazar el directorio single o - single objetivo (el objetivo assembly SOLO debe ejecutarse desde la línea de comandos) a una fase del ciclo de vida (package tiene sentido), algo así:

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

Adapta el elemento configuration para satisfacer tus necesidades (por ejemplo, con las cosas del manifiesto tal como se hablan).

 114
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-18 09:30:04

Si desea hacer un archivo jar ejecutable, también debe establecer la clase main. Así que la configuración completa debe 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>
 18
Author: abdiel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-29 17:18:13

Está el complemento shade maven. Se puede usar para empaquetar y renombrar dependencias (para omitir problemas de dependencia en el classpath).

 12
Author: Thomas Jung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-13 13:02:03

Si (como yo) no te gusta particularmente el enfoque jar-with-dependencies descrito anteriormente, la solución maven que prefiero es simplemente construir un proyecto de GUERRA, incluso si es solo una aplicación java independiente que está construyendo:

  1. Haga un proyecto maven jar normal, que construirá su archivo jar (sin las dependencias).

  2. Además, configure un proyecto maven war (con solo un src/main/webapp/WEB-INF/web vacío.xml, que evitará una advertencia / error en la compilación maven), que solo tiene su proyecto jar como una dependencia, y convierte su proyecto jar en <module> bajo su proyecto war. (Este proyecto de guerra es solo un truco simple para envolver todas sus dependencias de archivos jar en un archivo zip.)

  3. Construir el proyecto de guerra para producir el archivo de guerra.

  4. En el paso de implementación, simplemente cambie el nombre de su .war-archivo a *.zip y descomprimirlo.

Ahora debería tener un directorio lib (que puede mover donde quiera it) con su 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 más simple de configurar en maven (no hay necesidad de meterse con el plugin de ensamblaje) y también le da una vista más clara de la estructura de la aplicación (verá los números de versión de todos los jars dependientes a la vista, y evitar obstruir todo en un solo archivo jar).

 11
Author: Rop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-08 20:10:35

Puede 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>
 11
Author: lasantha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-25 15:37:37

Http://fiji.sc/Uber-JAR proporciona una excelente explicación de las alternativas:

Hay tres métodos comunes para construir un uber-JAR:

  1. Sin sombra. Desempaquetar todos los archivos JAR, luego volver a empaquetarlos en un solo FRASCO.
    • Pro: Funciona con el cargador de clases predeterminado de Java.
    • Con: Archivos presentes en varios archivos JAR con la misma ruta (p. ej., META-INF / services / javax.script.ScriptEngineFactory) sobrescribirá uno otro, lo que resulta en un comportamiento defectuoso.
    • Herramientas: Maven Assembly Plugin, Classworlds Uberjar
  2. Sombreado. Igual que unshaded, pero renombrar (es decir, "shade") 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 dependencias.
    • Con: Archivos presente en varios archivos JAR con la misma ruta (p. ej., META-INF / services / javax.script.ScriptEngineFactory) sobrescribirá uno otro, lo que resulta en un comportamiento defectuoso.
    • Herramientas: Maven Shade Plugin
  3. TARRO de tarros. El archivo JAR final contiene los otros archivos JAR incrustados dentro.
    • Pro: Evita los choques de versiones de dependencias. Todo los archivos fuente se conservan.
    • Con: Necesita agrupar un "bootstrap" classloader para habilitar Java para cargar clases desde el archivos JAR envueltos. La depuración de problemas del cargador de clases se vuelve más compleja.
    • Herramientas: Exportador de archivos JAR de Eclipse, Un FRASCO.
 9
Author: André Valenti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-07 23:41:44

Mi solución definitiva en Eclipse Luna y m2eclipse: Custom Classloader (descarga y añade a tu 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 classloader es lo mejor del classloader de una jarra 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 "
mvn clean dependency: copy-dependencies package
ser se creó un jar con dependencias en la carpeta lib con un cargador de clase 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>
 4
Author: Glaucio Southier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-28 16:01:39
        <!-- 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>            
 2
Author: Leslie Li,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-21 05:39:45

Dejando a un lado Maven, puedes poner bibliotecas JAR dentro del Jar Principal, pero necesitarás usar tu propio classloader.

Compruebe este proyecto: One-JAR link text

 1
Author: medopal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-13 13:56:40

Este post puede ser un poco viejo, pero también tuve el mismo problema recientemente. La primera solución propuesta por John Stauffer es buena, pero he tenido algunos problemas ya que estoy trabajando esta primavera. Los jars de dependencias de spring que uso tienen algunos archivos de propiedades y declaraciones xml-schemas que comparten las mismas rutas y nombres. Aunque estos jars provienen de las mismas versiones, el jar-with-dependencies maven-goal estaba sobrescribiendo estos archivos con el último archivo encontrado.

Al final, el la aplicación no pudo comenzar ya que los frascos de primavera no pudieron encontrar los archivos de propiedades correctos. En este caso la solución propuesta por Rop han resuelto mi problema.

También desde entonces, el proyecto spring-boot ahora existe. Tiene una forma genial de manejar este problema al proporcionar un objetivo maven que sobrecarga el objetivo del paquete y proporciona su propio cargador de clases. Ver Guía de Referencia de botas de resorte

 0
Author: Francois Gergaud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-08 18:18:55

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 plugin de dependencia se puede usar en la fase de paquete con el objetivo de copiar y descargará cualquier archivo en el repositorio Maven (incluidos los archivos WAR) y los escribirá donde sea que los necesite. Cambié el directorio de salida a project{project.construir.directory} / classes y luego el resultado final es que la tarea normal JAR 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>

 0
Author: millebi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:33

Gracias He añadido el siguiente fragmento en POM.archivo xml y problema Mp resuelto y cree un archivo fat jar que incluya todos los jars 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>
 0
Author: Rajeev Rathor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-17 09:36:09