java - pom - maven-resources-plugin
Maven: ¿cómo filtrar el mismo recurso varias veces con diferentes valores de propiedad? (4)
(...) Estoy bastante seguro de que esto se puede hacer, por ejemplo, a través del complemento antrun, pero no estoy familiarizado con eso. ¿Cuál es la forma más sencilla de lograr esto?
De hecho, podría usar resources:copy-resources
y varios <execution>
en su POM (tenga en cuenta que los resources:copy-resources
no permiten cambiar el nombre del archivo de destino).
Supongamos que tiene la siguiente estructura:
$ tree .
.
├── pom.xml
└── src
├── main
│ ├── filters
│ │ ├── filter-node1.properties
│ │ └── filter-node2.properties
│ ├── java
│ └── resources
│ ├── log4j.properties
│ └── another.xml
└── test
└── java
Donde log4j.properties
utiliza log4j.properties
posición y los archivos filter-nodeN.properties
contienen los valores. Por ejemplo:
# filter-node1.properties
log.location=D:/logs
log.file.postfix=_1
Luego, en su pom.xml
, configure el complemento de recursos y defina una <execution>
por nodo para llamar a copy-resources
con un directorio de salida específico y un filtro específico para usar:
<project>
...
<build>
<resources>
<!-- this is for "normal" resources processing -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering><!-- you might still want to filter them -->
<excludes>
<!-- we exclude the file from "normal" resource processing -->
<exclude>**/log4j.properties</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources-node1</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/node1</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/log4j.properties</include>
</includes>
</resource>
</resources>
<filters>
<filter>src/main/filters/filter-node1.properties</filter>
</filters>
</configuration>
</execution>
<execution>
<id>copy-resources-node2</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/node2</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/log4j.properties</include>
</includes>
</resource>
</resources>
<filters>
<filter>src/main/filters/filter-node2.properties</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Ejecutar mvn process-resources
produciría el siguiente resultado:
$ tree .
.
├── pom.xml
├── src
│ ├── main
│ │ ├── filters
│ │ │ ├── filter-node1.properties
│ │ │ └── filter-node2.properties
│ │ ├── java
│ │ └── resources
│ │ ├── log4j.properties
│ │ └── another.xml
│ └── test
│ └── java
└── target
├── classes
│ └── another.xml
├── node1
│ └── log4j.properties
└── node2
└── log4j.properties
Con los valores adecuados en cada log4j.properties
.
$ cat target/node1/log4j.properties
log4j.appender.Application.File=D:/logs/application_1.log
log4j.appender.tx_info.File=D:/logs/tx_info_1.log
Esto funciona un poco, pero es detallado y esto podría ser un problema si tiene una cantidad decente de nodos.
Traté de escribir algo más conciso y mantenible utilizando el Complemento AntRun de Maven, pero no pude hacer que la tarea de . ant-contrib
trabajara con Maven (por una razón desconocida, no se reconoce la tarea) y me rendí
Aquí hay una alternativa utilizando el complemento Antvenr de Maven. Nada complicado, sin bucle, solo estoy copiando el archivo de origen a otra ubicación, cambiando su nombre sobre la marcha y filtrando el contenido:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>copy-resources-all-nodes</id>
<phase>process-resources</phase>
<configuration>
<tasks>
<copy file="src/main/resources/log4j.properties" toFile="target/antrun/log4j-node1.properties">
<filterset>
<filter token="log.location" value="D:/logs"/>
<filter token="log.file.postfix" value="_1"/>
</filterset>
</copy>
<copy file="src/main/resources/log4j.properties" toFile="target/antrun/log4j-node2.properties">
<filterset>
<filter token="log.location" value="D:/logs"/>
<filter token="log.file.postfix" value="_2"/>
</filterset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Tenga en cuenta que Ant utiliza @
de forma predeterminada como delimitadores para el token (no se pudo usar un delimitador de estilo log4j.properties
), por lo que log4j.properties
convirtió en:
[email protected]@/[email protected]@.log
[email protected]@/[email protected]@.log
Pero, dado que estos valores parecen ser específicos del nodo, ¿consideraste usar propiedades del sistema (que podrías colocar en los scripts de inicio)? Esto es algo que ya he hecho (con un log4j.xml
), funciona bien y simplificaría mucho las cosas.
Nuestro proyecto utiliza Log4J, configurado a través del archivo log4j.properties. Tenemos varios servidores de producción, que se registran en diferentes archivos de registro, de modo que los registros se pueden diferenciar. Entonces log4j.properties para el nodo 1 se ve así:
...
log4j.appender.Application.File=D:/logs/application_1.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_1.log
...
mientras que log4j.properties para el nodo 2 parece
...
log4j.appender.Application.File=D:/logs/application_2.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_2.log
...
Ya usamos los perfiles de Maven para generar la configuración de nuestro servidor. Hasta ahora contenía varios archivos log4j.properties distintos que diferían solo en los nombres de archivo de registro como se muestra arriba. Me gustaría generar estos archivos con Maven usando un archivo de plantilla de recursos como este:
...
log4j.appender.Application.File=${log.location}/application${log.file.postfix}.log
...
log4j.appender.tx_info.File=${log.location}/tx_info${log.file.postfix}.log
...
Es fácil ejecutar Maven varias veces con diferentes valores de ${log.file.postfix}
para generar un único archivo de propiedades de registro diferente cada vez. Sin embargo, lo que me gustaría es generar un archivo de propiedades distinto (con el nombre / ruta diferente) para cada servidor en una compilación . Estoy bastante seguro de que esto se puede hacer, por ejemplo, a través del complemento antrun, pero no estoy familiarizado con eso. ¿Cuál es la forma más sencilla de lograr esto?
Aquí hay algunos enfoques que puedes probar:
use el complemento antrun y la tarea de
copy
para hacer duplicados de su archivo de recursos en la fase degenerate-resources
. Un ejemplo del uso del complemento antrun se proporciona en la respuesta a esta pregunta SO sobre la copia con maven . Incluso podría usar la expansión de propiedades de ant para expandir cada $ {log.file.postfix} a un valor distinto, ya sea los valores literales, 1,2,3, etc. o marcadores de posición únicos, $ {log.file.postfix1}, $ { log.file.postfix2} que finalmente se reemplazan cuando maven realiza el filtrado de recursos.En lugar de usar antrun, use su sistema de control de versiones para configurar varias copias del mismo archivo. A continuación, puede ejecutar varias instancias de los resources:copy-resources objetivo de resources:copy-resources , cada uno con diferentes valores de propiedad configurados y un nombre de archivo de destino diferente.
Aunque esto es un poco viejo, encontré el hilo recientemente y me gustaría proponer una solución actualizada utilizando el plugin iterator-maven-plugin. Una descripción general se encuentra aquí: http://khmarbaise.github.io/iterator-maven-plugin/
Un ejemplo específico de cómo puede lograr su objetivo sería combinar el complemento iterador con un recurso de copia y un filtro habilitado. Incluso podría agregar un archivo de propiedades personalizadas para usar como filtro en caso de que tenga otros atributos que sean únicos por nodo con este enfoque.
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.3</version>
<executions>
<execution>
<id>configure-log-properties</id>
<phase>validate</phase>
<goals>
<goal>iterator</goal>
</goals>
<configuration>
<iteratorName>log.file.postfix</iteratorName>
<content>1,2,3,4,5</content>
<pluginExecutors>
<pluginExecutor>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
</plugin>
<goal>copy-resources</goal>
<configuration>
<outputDirectory>${project.build.directory}/nodes/${log.file.postfix}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>log4j.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>
Si hay muchas configuraciones de destino que deben copiarse, puede utilizar el complemento maven-antrun-plug junto con ant macrodef.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>copy-resources-all-nodes</id>
<phase>process-resources</phase>
<configuration>
<tasks>
<macrodef name="copyConfigFile">
<attribute name="node"/>
<sequential>
<copy file="src/main/resources/log4j.properties"
toFile="target/antrun/log4j-@{node}.properties">
<filterset>
<!-- put the node-specific config in property files node1.properties etc -->
<filtersfile file="config/@{node}.properties"/>
</filterset>
</copy>
</sequential>
</macrodef>
<copyConfigFile node="node1"/>
<copyConfigFile node="node2"/>
<copyConfigFile node="node3"/>
...
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Si realmente tiene muchas configuraciones de destino, también podría usar ant-contrib para iterar sobre una lista de configuraciones de destino.
Hay un ejemplo de cómo hacer esto here