java - plugin - packaging ear</ packaging
Complemento para el oído de Maven: artefacto "doble" cuando no se usa limpio (3)
Cuando construí una oreja a través del plugin de Maven, experimenté que la aplicación de un package
sin clean
puede llevar a resultados inconsistentes: si cambio la versión de una dependencia, la dependencia ahora aparece dos veces en el oído, en la versión anterior y en la nueva. Si construyo el oído sin números de versión en los nombres de los tarros, solo obtengo un tarro, pero las versiones antiguas no se reemplazan correctamente.
Miré el código fuente
Especialmente las líneas de 436 son interesantes: verifica si actualizar archivos en destino, pero aparentemente solo verifica la ruta absoluta y la última fecha de modificación.
Resumido: ¿Tengo razón en que cambiar las dependencias (o sus versiones) siempre requiere una clean
antes de la compilación? ¿O hay algo de inteligencia en el package
que perdí?
El archivo de ear agrupa todas las dependencias del proyecto en un zip (siguiendo una estructura especificada por el formato de ear). El archivo se construye en dos fases, primero el plugin ear-maven recopila las dependencias del proyecto y luego crea el archivo. Estas dependencias se copian en el $ {project.build.directory}.
Por lo tanto, la limpieza siempre debe usarse con este complemento, para evitar cualquier inconsistencia causada por la adición de dependencias en un directorio donde una ejecución anterior podría haber copiado otra instantánea de las dependencias. Si se omite la fase de limpieza, el directorio $ {project.build.directory} no se truncará, lo que probablemente causará inconsistencias en el paquete construido.
Vea si el problema persiste compilando la última versión de maven-ear-plugin (3.0.0, más reciente que 2.10.2, más reciente que la oficial 2.12.1 )
Como puede ver en el último código EarMojo.java
, la función copyModules()
ha cambiado desde la implementación de la versión 2.10.1 y podría ser más robusta.
Sí ... la mayoría de las veces debería llamar clean
cuando cambie sus dependencias o cualquier otra configuración de compilación, de lo contrario, los elementos de compilación anteriores pueden colisionar con una nueva compilación (como parece ser su caso aquí). En términos generales, para asegurarse de que los elementos de la compilación anterior no coincidan con una compilación nueva, debe llamar clean
de antemano, cambios de configuración o no.
Pero hay excepciones: si está seguro de que los elementos de compilación anteriores no afectarán su nueva compilación, puede omitir la clean
. Sin embargo, la mayoría de las veces no puede saberlo, o simplemente no es posible saltearse sin causar tales colisiones. Explico en detalle a continuación.
Cuando construya su proyecto con Maven, generará archivos y otros elementos en la carpeta ${project.build.directory}
( target
por defecto). Estos elementos se utilizan para crear su artefacto (EAR en su caso) durante la fase del package
.
Sin llamar clean
después de una construcción, todos los elementos bajo el target
seguirán estando allí durante la próxima construcción y pueden impactarlo. ¿Cómo pueden los complementos de Maven diferenciar y saber qué elementos son de versiones anteriores o nuevas? Obviamente, la marca de tiempo de los archivos no es suficiente y, a menos que se use algún mecanismo de ocultación para identificar qué archivos provienen de qué compilación, es difícil hacerlo.
Si cambio la versión de una dependencia, la dependencia ahora aparece dos veces en el oído, en la versión anterior y en la nueva.
Esto probablemente se deba a que las dependencias de copia de compilación en el target
y su complemento de empaquetado incluirán un directorio completo en el artefacto generado (en su caso, el EAR). Por ejemplo, si ejecuta su compilación dos veces con una versión diferente:
- Primera compilación:
mydep-1.0.jar
se genera entarget/classes/mydep
y su complemento incluye todos los archivos detarget/classes/mydep
en el EAR. Todo está bien. - Segunda compilación: se genera
mydep-1.0.jar
peromydep-1.0.jar
aún está entarget/classes/mydep
. Setarget/classes/mydep
directoriotarget/classes/mydep
y ambas versiones terminan en el EAR.
Si construyo el oído sin números de versión en los nombres de los tarros, solo obtengo un tarro, pero las versiones antiguas no se reemplazan correctamente.
Esto se debe a que algunos complementos, para optimización, no volverán a compilarse ni a volver a realizar las acciones si ven que los resultados ya existen. En su caso, como señaló, el complemento EAR probablemente conserva la versión "antigua" del archivo porque ya existe, donde de hecho una versión más reciente con el mismo nombre debería reemplazarlo. Eso es probablemente porque no especificaste una versión:
- En el primer caso,
mydep-0.1.jar
existió y se creó un nuevomydep-0.2.jar
pero ambos se incluyeron en su EAR - Ahora, sin la versión, tiene
mydep.jar
que no estámydep.jar
por la versión más reciente porque "ya existe", por lo que el archivo "antiguo" permanece en su lugar y se incluye en el EAR.
Conclusión: los complementos de Maven no pueden diferenciarse con una certeza del 100% si un elemento es de una compilación anterior o una nueva. Cuando actualice la configuración de su compilación, siempre debe llamar clean
para asegurarse de que no habrá una colisión entre los elementos de compilación nuevos y antiguos. Incluso sin cambios en la configuración de la compilación, puede ser necesario llamar clean
, pero eso es otro asunto.
Recomendaría llamar siempre clean
cuando se ejecuta una compilación, a menos que no sea posible una colisión y proporcione un valor real, como una ganancia de tiempo, porque la reconstrucción de todo el proyecto es demasiado larga u otras razones que lo justifican.
EDITAR: según la solicitud de fuentes de @JF Meier, la guía de Running Maven proporciona consejos según el objetivo clean
y los riesgos de inconsistencia relacionados:
Salida inconsistente
La mayoría de los complementos están optimizados para saber si tienen que ejecutar su tarea. En algunos casos, la salida se puede contaminar de una compilación anterior y el resultado final no es el esperado. En situaciones excepcionales, puede llamar a la fase de
clean
, lo que significa: eliminar el directorio de salida. También puede llamarlo comomvn clean verify
que significa: primero limpie el directorio de salida, luego genere el proyecto y verifique el resultado.