java - maven-assembly-plugin: cómo usar appendAssemblyId
(1)
Tengo un proyecto de varios módulos de Maven y en un módulo quiero crear dos artefactos durante la compilación:
- El artefacto principal, que es una biblioteca jar, dependerá de algunos de los otros módulos.
- Un archivo jar ejecutable que ejecuta algunas funciones de ayuda. Ningún otro módulo depende de esto y solo está destinado a que el usuario lo ejecute manualmente en ciertas situaciones.
Aquí está el código que utilizo para configurar el maven-assembly-plugin
:
<plugin>
<artifactId>
maven-assembly-plugin
</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>dist-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>bso</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>helper-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>HelperMain<mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Estoy configurando appendAssemblyId
en false
porque, de lo contrario, -jar-with-dependencies
se agregará al nombre final y no veo la necesidad de hacerlo. Omitirlo da un nombre de archivo más limpio y fácil de usar.
Cuando ejecuto mvn integration-test
, recibo las siguientes advertencias:
[ADVERTENCIA] Opciones de configuración: ''appendAssemblyId'' está configurado como falso, y falta ''clasificador''. En lugar de adjuntar el archivo de ensamblaje: [...] / target / helper-5.0.0-SNAPSHOT.jar, se convertirá en el archivo para el artefacto del proyecto principal.
NOTA: Si se proporcionan múltiples descriptores o formatos de descriptores para este proyecto, el valor de este archivo no será determinista.
[ADVERTENCIA] Reemplazando el archivo de artefacto principal del proyecto preexistente: [...] / target / my.module-5.0.0-SNAPSHOT.jar con el archivo de ensamblaje: [...] / target / helper-5.0.0- SNAPSHOT.jar
Hay dos cosas que me irritan:
A pesar del hecho de que la advertencia dice que reemplazará my.module-5.0.0-SNAPSHOT.jar con helper-5.0.0-SNAPSHOT.jar, en realidad no lo hace y cuando la compilación ha finalizado, ambos archivos aún tienen tamaños diferentes.
¿Por qué aparece la advertencia de reemplazar el artefacto?
Parece que el
classifier
está en desuso, ¿por qué la advertencia me pide que lo use?
Eso es porque estás malinterpretando las advertencias.
Recapitulemos. Un proyecto de Maven que no es del tipo pom
siempre producirá, de forma predeterminada, lo que se denomina un artefacto principal. Para un JAR, este artefacto es el resultado de empaquetar las fuentes compiladas en un JAR; Para un WAR, es el resultado de construir la aplicación web.
Lo que es importante recordar es que este artefacto se adjunta al proyecto: esta terminología es útil cuando se instala el proyecto (con mvn install
), implementado (con mvn deploy
) o liberado (con el maven-release-plugin
). Adjunto significa que este artefacto se instalará / desplegará / liberará cuando el proyecto se encuentre. No todos los archivos generados durante una compilación de Maven (básicamente, todo lo que está debajo de la carpeta de target
) son; Sólo los archivos que se adjuntaron. Como tal, puede crear una gran cantidad de archivos bajo el target
pero tener un único artefacto instalado.
Junto con este artefacto principal, es posible que desee que su compilación produzca otros artefactos para instalar o implementar. Ese es el concepto de artefactos adjuntos adicionales o secundarios. Los ejemplos principales son el Javadoc o las fuentes: normalmente, cuando se lanza un proyecto, su Javadoc y sus fuentes también lo son. Y ahí es donde entra en juego el classifier
nociones .
En un repositorio de Maven, todos y cada uno de los archivos deben seguir la misma convención de denominación: artifactId-version(-classifier).type
. Cada artefacto secundario tendrá el mismo GAV (ID de grupo, ID de artefacto, versión) que el artefacto principal, por lo que si desea colocar en un repositorio de Maven 1 artefacto principal y 1 artefacto adjunto (como sería el caso de un JAR principal a lo largo de con sus fuentes JAR Javadoc y JAR), necesita alguna forma de distinguirlos. Para qué sirve el classifier
: distingue los artefactos secundarios del artefacto principal.
Volvamos a su ejemplo ahora. Su proyecto Maven, que es de empaquetado en jar
, producirá por defecto un artefacto JAR principal llamado my.module-5.0.0-SNAPSHOT.jar
; aún de manera predeterminada, este JAR principal se adjunta al proyecto (y está listo para ser instalado / implementado). Ahora está configurando el maven-assembly-plugin
para crear un nuevo artefacto JAR (llamado helper-5.0.0-SNAPSHOT.jar
pero realmente no importa). El Complemento de ensamblaje, de forma predeterminada, se adjunta al proyecto del artefacto que produce . Así que terminas con 2 artefactos adjuntos.
- teniendo la misma identificación de artefacto de
my.module
; el hecho de que el archivo en el disco dentro de la carpeta detarget
se llamehelper
para uno es irrelevante, solo importan las coordenadas GAV - Teniendo la misma versión de
5.0.0-SNAPSHOT
- Teniendo el mismo embalaje de jar
Y ningún clasificador para distinguirlos. Esto es lo que genera la advertencia: usted termina adjuntando al proyecto un artefacto secundario que reemplaza efectivamente al principal, simplemente porque tiene las mismas coordenadas. Entonces el resultado es:
- Ambos archivos tienen nombres diferentes en el disco dentro del
target
, pero eso es irrelevante porque - Ambos comparten las mismas coordenadas por lo que solo 1 sobrevivirá.
Es el producido por el Complemento de ensamblaje que ganará el conflicto y reemplazará el artefacto principal adjunto.
Si desea convencerse de todo esto, ejecute mvn clean install
en el proyecto y verifique su repositorio local. Notará que solo se instalará el artefacto jar-with-dependencies
. El otro (el artefacto principal) fue poof.
También puede configurar un <distributionManagement>
:
<distributionManagement>
<repository>
<id>local-repo-test</id>
<url>file://...</url>
</repository>
</distributionManagement>
e invocar a mvn clean deploy
. A continuación, puede comprobar que el único artefacto implementado será el jar-with-dependencies
.
Nota final: Sí, el parámetro de classifier
Complemento de ensamblaje está en desuso, ya que solo debe usar el ID de ensamblaje como clasificador.