8

Uso el complemento de ensamblaje de Maven para crear un ensamblaje para mi proyecto de varios módulos. Hay dos aplicaciones separadas creadas a partir de este proyecto de varios módulos, cada una con un conjunto separado de dependencias. Hice un descriptor de ensamblaje personalizado que ensambla dos directorios (para cada aplicación) con compilaciones de módulos y sus respectivas dependencias. Hace todo bien, pero una cosa: pone las dependencias de ambos módulos en el conjunto del otro.Administración de dependencias de varios módulos con el complemento de ensamblaje de Maven

La siguiente es una versión simplificada de mi proyecto, que tiene exactamente el mismo comportamiento.

Considérese un proyecto que consta de dos módulos y un módulo de montaje: dependencias

APP 
    module1 
    module2 
    assembly 

he añadido puramente para la demostración:

com.test.app:module1:jar:1.0 
\- commons-cli:commons-cli:jar:1.2:compile 

com.test.app:module2:jar:1.0 
\- commons-daemon:commons-daemon:jar:1.0.8:compile 

Aquí está el POM padres:

<project> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    <packaging>pom</packaging> 

    <modules> 
    <module>module1</module> 
    <module>module2</module> 
    <module>assembly</module> 
    </modules> 
</project> 

module1 POM:

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>module1</artifactId> 
    <version>1.0</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>commons-cli</groupId> 
     <artifactId>commons-cli</artifactId> 
     <version>1.2</version> 
    </dependency> 
    </dependencies> 
</project> 

modulo2 POM:

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>module2</artifactId> 
    <version>1.0</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>commons-daemon</groupId> 
     <artifactId>commons-daemon</artifactId> 
     <version>1.0.8</version> 
    </dependency> 
    </dependencies> 
</project> 

montaje POM:

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>assembly</artifactId> 
    <version>1.0</version> 
    <packaging>pom</packaging> 

    <build> 
    <plugins> 
     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <version>2.2.2</version> 

     <executions> 
      <execution> 
      <id>make-assembly</id> 
      <phase>package</phase> 

      <goals> 
       <goal>single</goal> 
      </goals> 
      </execution> 
     </executions> 

     <configuration> 
      <appendAssemblyId>false</appendAssemblyId> 

      <descriptors> 
      <descriptor>src/main/assembly/descriptor.xml</descriptor> 
      </descriptors> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
</project> 

Y, por último, el descriptor de montaje:

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>dir</format> 
    </formats> 

    <moduleSets> 
    <moduleSet> 
     <useAllReactorProjects>true</useAllReactorProjects> 

     <includes> 
     <include>com.test.app:module1:jar</include> 
     </includes> 

     <binaries> 
     <outputDirectory>module1</outputDirectory> 
     <unpack>false</unpack> 

     <dependencySets> 
      <dependencySet> 
      <unpack>false</unpack> 
      </dependencySet> 
     </dependencySets> 
     </binaries> 
    </moduleSet> 

    <moduleSet> 
     <useAllReactorProjects>true</useAllReactorProjects> 

     <includes> 
     <include>com.test.app:module2:jar</include> 
     </includes> 

     <binaries> 
     <outputDirectory>module2</outputDirectory> 
     <unpack>false</unpack> 

     <dependencySets> 
      <dependencySet> 
      <unpack>false</unpack> 
      </dependencySet> 
     </dependencySets> 
     </binaries> 
    </moduleSet> 
    </moduleSets> 
</assembly> 

Como se puede ver, el montaje se unen para empaquetar fase . Así que, cuando yo haga

mvn package 

del directorio padre, tengo el siguiente montaje

module1/ 
    commons-cli-1.2.jar 
    commons-daemon-1.0.8.jar 
    module1-1.0.jar 
module2/ 
    commons-cli-1.2.jar 
    commons-daemon-1.0.8.jar 
    module2-1.0.jar 

Básicamente, el problema aquí es que el módulo 1 no depende de los Comunes-daemon, pero el plugin de montaje ha incluido la dependencia. Del mismo modo, con module2 y commons-cli.

¿Alguien puede explicar por qué el plugin de ensamblaje se comporta de esta manera?

¿Cuál sería una solución?

+0

No esperaría este comportamiento extraño de 'maven-assembly-plugin' ... ¿Está seguro de que no hay dependencias empujadas a su proyecto de ensamblaje desde el elemento primario? Muéstranos el árbol de dependencias generado para el proyecto de ensamblaje. –

+0

El árbol de dependencias para el módulo de ensamblaje está obviamente vacío, ya que su POM no tiene declaraciones de dependencia. – sertsy

Respuesta

10

Siempre he tenido experiencias similares usando el plugin de ensamblaje con proyectos de varios módulos donde el resultado final no fue el esperado. Espero que alguien más pueda dar una respuesta más precisa sobre por qué está sucediendo y cuál es la mejor manera de utilizar esos dos conceptos en conjunto.

Dicho esto, un posible problema sería tener module1 y module2 generando sus propios artefactos de ensamblaje que contienen sus respectivas jarras y dependencias. Luego puede modificar el archivo pom del submódulo de ensamblaje para que tenga dependencias en los artefactos de distribución generados de sus módulos hermanos y luego descomprimirlos en un nuevo ensamblaje.

En los archivos pom del Módulo1 y del Módulo2, puede agregar una configuración de complemento de ensamblaje a su fase de paquete de forma similar a como lo hizo con el submódulo de ensamblaje.

<build> 
    <plugins> 
     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <version>2.2.2</version> 

     <executions> 
      <execution> 
      <id>make-assembly</id> 
      <phase>package</phase> 
      <goals> 
       <goal>single</goal> 
      </goals> 
      </execution> 
     </executions> 

     <configuration> 
      <descriptors> 
      <descriptor>src/main/assembly/descriptor.xml</descriptor> 
      </descriptors> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 

módulo 1 tendría un src/main/montaje/descriptor.xml como esto

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>zip</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <outputDirectory>module1</outputDirectory> 
     <unpack>false</unpack> 
    </dependencySet> 
    </dependencySets> 
</assembly> 

Y Module2 tendrá un parecido src/main/montaje/descriptor.xml

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>zip</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <outputDirectory>module2</outputDirectory> 
     <unpack>false</unpack> 
    </dependencySet> 
    </dependencySets> 
</assembly> 

Luego, en el ensamblado/pom.xml, agregará los artefactos Zip del Módulo 1 y 2 como dependencias

<dependencies> 
    <dependency> 
     <groupId>com.test.app</groupId> 
     <artifactId>module1</artifactId> 
     <version>1.0</version> 
     <type>zip</type> 
     <classifier>distribution</classifier> 
    </dependency> 
    <dependency> 
     <groupId>com.test.app</groupId> 
     <artifactId>module2</artifactId> 
     <version>1.0</version> 
     <type>zip</type> 
     <classifier>distribution</classifier> 
    </dependency> 
    </dependencies> 

... y recortar el montaje/fichero src/montaje/descriptor.xml/principal de este aspecto

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>dir</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <useTransitiveDependencies>false</useTransitiveDependencies> 
     <unpack>true</unpack> 
    </dependencySet> 
    </dependencySets> 

</assembly> 

Como dije esto sería una obra posible alrededor y por desgracia añade una cantidad significativa de configuración XML adicional para su proceso de compilación. Pero funciona.

+1

Gracias, por una respuesta, Keith. Por lo que entiendo, en el ejemplo que ha mostrado, si ejecuto el 'mvn package' desde el POM padre, primero ensamblaría el módulo1, luego el módulo2 y el módulo de ensamblaje de empaque solo pondrían los primeros dos ensamblajes juntos. Sin embargo, esto devora el propósito de un módulo de ensamblaje separado. La idea detrás de un módulo separado para un ensamblaje es asegurarse de que todos los módulos se hayan construido cuando se crea el ensamblaje. – sertsy

+0

Supongamos que tengo otro módulo - module3 que es una dependencia para module1. Si en la fase del paquete del módulo1, el módulo3 todavía no está construido, el módulo1 no podrá producir un ensamblaje (ya que el ensamblaje está vinculado a una fase del paquete). Es por eso que el módulo de ensamblaje siempre se coloca al final, para asegurarse de que ya se hayan construido otros módulos. Lo que sugieres podría funcionar en el ejemplo que he dado, pero creo que no es el correcto. Espero haber aclarado mis pensamientos. – sertsy

+1

El orden de los módulos enumerados en el pom principal no es relevante. El reactor maven construirá todas las dependencias en el orden correcto de compilación, que sabe cómo hacerlo porque el pom de ensamblado tiene el módulo 1 y el módulo 2 como dependencias. Incluso si agrega module3 como una dependencia para module1, primero compilará module3, luego module1, module2, terminando con assembly. – Keith

Cuestiones relacionadas