tutorial - Leyendo el archivo de propiedades del archivo POM en Maven
super pom (2)
¿Por qué esto NO funciona? Cómo elegir los números de versión del archivo de propiedades.
Leyendo propiedades en pom.xml
<project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
</execution>
<configuration>
<files>
<file>dev.properties</file>
</files>
</configuration>
</executions>
</plugin>
</plugins>
</build>
</project>
En dev.properties
org.aspectj.aspectjrt.version = 1.6.11
Dependencia en pom.xml
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj.aspectjrt.version}</version>
</dependency>
Error: la dependencia debe ser una versión válida
Cuando inicia Maven desde la línea de comando, pasa por varias etapas. Aquí hay una pseudo descripción de estas etapas, estoy simplificando intencionalmente la secuencia exacta (con el riesgo de decir cosas que son un poco incorrectas / fuera de orden) para que pueda ver por qué no puede funcionar lo que está tratando de hacer.
Primero analiza su línea de comandos, todas las propiedades definidas en la línea de comandos que usan el
-Dname=value
se inyectan en elMavenSession
Las opciones de línea de comando que definen el reactor se verifican para decidir cuál debe ser la lista de proyectos a construir (también conocido como el reactor).
-N
significa compilar solo la raízpom.xml
,-pl
permite especificar una lista de módulos para compilar,-am
y-amd
permite agregar módulos ascendentes o descendentes, respectivamente, de los especificados por-pl
. Maven no ha analizado ningún archivopom.xml
en este momento.Las reglas de activación del perfil
-P
se analizan para ver qué perfiles activar.Ahora Maven tiene el conocimiento suficiente para comenzar a analizar los archivos
pom.xml
. Comienza cargando y analizando la raízpom.xml
, es decir, la que está en el directorio actual (o si especificó unapom.xml
alternativa con-f
entonces esa). Este análisis inicial solo se concentra en averiguar la lista de proyectos para construir. La activación del perfil solo se considera en la medida en que puede afectar a la lista de<modules>
que están disponibles. Las coordenadas de Id. De grupo, Id. De artefacto, Versión y Empaquetado en elpom.xml
no pueden contener propiedades porque el análisis de las propiedades en elpom.xml
no ha tenido lugar en este momento. (El lector observador también verá que esto también explica por qué no puede activar perfiles basados en propiedades dentro delpom.xml
, ya que solo las propiedades del sistema se han analizado en esta etapa)Una vez que se ha validado el conjunto de proyectos, Maven ahora realiza un análisis más de esos archivos
pom.xml
para construir la lista de extensiones de compilación (si las hay) y la lista de complementos. En esta etapa, el análisis requiere la evaluación de las<properties>
en cada proyecto, por lo que es cuando estos se evalúan y se "inyectan" en el modelo efectivo. Por lo tanto, puede usar las propiedades del sistema y las propiedades pom para definir las coordenadas y dependencias adicionales dentro de (xpath)/project/build/extensions
,/project/build/pluginManagement/plugins/plugin
,/project/build/pluginManagement/plugins/plugin/dependencies
,/project/build/plugins/plugin
y/project/build/plugins/plugin/dependencies
.Ahora Maven comienza a analizar la lista de objetivos y fases especificadas en la línea de comandos. Los objetivos parcialmente especificados se evalúan para una coincidencia con la lista de complementos. La coincidencia debe ser única para todos los proyectos contra los que se ejecutará el objetivo del complemento (es decir, si se trata de un objetivo agregador, la coincidencia solo se requiere en la raíz, pero para todos los demás objetivos "normales", el nombre corto del complemento debe ser El mismo plugin para todos los proyectos). Las fases del ciclo de vida deben ser de uno de los ciclos de vida predeterminados o de un ciclo de vida definido en una extensión de compilación.
A partir de la lista analizada de objetivos y fases, Maven construye el plan de construcción, es decir, qué va a hacer en qué proyectos y en qué orden. Para hacer esto, Maven debe analizar la lista de dependencias del proyecto definidas en los archivos
pom.xml
proyectos del reactor. Esto se debe a que otro proyecto dentro del reactor puede generar una dependencia, lo que obliga a una secuenciación de la ejecución del proyecto. Por lo tanto, puede usar las propiedades del sistema y las propiedades pom para definir las coordenadas y dependencias adicionales dentro de (xpath)/project/dependencyManagement/dependencies/dependency
y/project/dependencies/dependency
pero tenga en cuenta que en este momento no se han ejecutado complementos.Ahora que Maven tiene el plan de construcción, comienza a seguir ese plan en el orden en que se construyó. Si el primer objetivo / fase en el CLI fue un objetivo, se invocará ese objetivo. Si el primer objetivo / fase fue una fase del ciclo de vida de compilación predeterminado, Maven comenzará con la fase de
initialize
y ejecutará todos los complementos vinculados a esa fase ... continuando de manera similar a lo largo de la lista de fases y luego la lista de proyectos Tenga en cuenta también que la fase deinitialize
solo se ejecuta como parte del ciclo de vida de compilación predeterminado. No se ejecuta en los ciclos de vida predeterminados de limpieza o predeterminados del sitio, y no se ejecuta en ningún ciclo de vida personalizado. (El lector observador concluirá que esto resalta otro problema con la técnica que la pregunta está intentando). Nota: tenga en cuenta que los objetivos del agregador forman una "ruptura" en el reactor, por lo tanto, si le pide a Maven que ejecuteclean package foo:bar site
dondefoo:bar
es un objetivo mojo del agregador, entoncesclean package
se ejecutará en todos los proyectos en el reactor, luegofoo:bar
se ejecutará contra la raíz, luego elsite
se ejecutará contra todos los proyectos en el reactor. En otras palabras, el plan de compilación tomará la ejecución continua más larga de objetivos y fases no agregadores, dividida por las corridas continuas más largas de objetivos agregados.Antes de llamar a cada mojo (es decir, objetivo vinculado a una fase o directamente especificado desde la línea de comandos), Maven evalúa el
pom.xml
para la<configuration>
efectiva de ese mojo. En este punto, Maven tiene disponibles las propiedades del sistema, las propiedades especificadas en el pom y cualquier propiedad inyectada en elMavenSession
por mojos ejecutados previamente. Por lo tanto, la<configuration>
puede hacer referencia a cualquiera de esas propiedades ...Aparte
Ahora hay una advertencia ... si dice set (xpath)
/project/build/directory
to${some-property-i-will-set-via-a-mojo}
y luego hace referencia a eso desde su<configuration>
, Bueno, la triste noticia es que (xpath)/project/build/directory
se habrá evaluado en elpom.xml
efectivo antes de cualquier ejecución del complemento, por lo que${project.build.directory}
habrá recibido el valor literal${some-property-i-will-set-via-a-mojo}
y es de tipojava.io.File
en elMavenProject
así que lo que realmente habrá sucedido es unnew File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}")
. Si el campo<configuration>
que está inyectando es de tipoFile
, no se requerirá la conversión de tipo y, por lo tanto, el valor se inyectará directamente y no se habrá producido ninguna sustitución de propiedad.Hay otros casos de borde, como el descrito anteriormente, pero en general la sustitución de propiedades funcionará con propiedades "inyectadas con mojo" (como las proporcionadas por el complemento de propiedades de Mojo ) en las secciones
<configuration>
. No funcionará fuera de esas secciones.
Así que aquí está la rápida regla de oro de Stephen para los diferentes tipos de propiedades:
Propiedades del sistema
Estos funcionan en todas partes ... pero son extremadamente peligrosos en /project/(parent/)?/(groupId|artifactId|version|packaging)
ya que no tiene control alguno sobre las propiedades del sistema que se definirán cuando se ejecute el proyecto. Como una dependencia transitiva. El uso de ${...}
expansión dentro de /project/(parent/)?/(groupId|artifactId|version|packaging)
debe considerar como equivalente a conducir un auto a 200 km / h con una punta de metal de 30 cm (12 pulgadas) que sobresale de el volante en lugar de una bolsa de aire ... ah y sin cinturón de seguridad ... y acabas de tener 10 unidades de alcohol y dos líneas de cocaína.
Propiedades de pom.xml
(y propiedades de settings.xml
)
Estos funcionan en la mayoría de los lugares, pero nunca están disponibles en /project/(parent/)?/(groupId|artifactId|version|packaging)
(ya que no se analizaron cuando se están evaluando esos campos) y no están disponibles para su consideración los perfiles activos (de nuevo, ya que no se han analizado cuando se está evaluando la activación del perfil)
Mojo inyecta propiedades
Estos trabajos funcionan dentro de las secciones de <configuration>
y pueden (debido a la interpolación recursiva de los parámetros de Mojo String
inyectados) funcionan indirectamente, pero dada la incertidumbre involucrada, la recomendación es restringir su uso a la sección <configuration>
de los complementos e informes. .
Una cosa final
Piense en lo que sucede cuando su proyecto aparece como una dependencia. Si ha especificado sus dependencias utilizando un mojo para extraerlas de un archivo .properties
en el disco, Maven no tiene forma de replicar eso cuando su dependencia se extrajo del repositorio de Maven. Así que Maven no podría determinar las dependencias. Por lo tanto, nunca podría funcionar.
Lo que podría hacer es usar un sistema externo (por ejemplo, ANT) para generar el pom.xml
partir de una plantilla con las versiones reemplazadas en ese archivo. Y luego usa la plantilla instanciada para construir.
Este archivo de properties(dev.properties)
para el trabajo de compilación.
<files>
<file>dev.properties</file>
</files>
Para la dependencia necesita agregar como a continuación en su archivo pom.xml.
<properties>
<org.aspectj.aspectjrt.version>1.6.11</org.aspectj.aspectjrt.version>
</properties>