Java Maven:如何使用不同的属性值多次过滤同一资源?

Java Maven:如何使用不同的属性值多次过滤同一资源?,java,resources,maven-2,filtering,maven-antrun-plugin,Java,Resources,Maven 2,Filtering,Maven Antrun Plugin,我们的项目使用Log4J,通过Log4J.properties文件配置。我们有多个生产服务器,它们将日志记录到不同的日志文件,因此可以区分日志。节点1的log4j.properties如下所示: ... log4j.appender.Application.File=D:/logs/application_1.log ... log4j.appender.tx_info.File=D:/logs/tx_info_1.log ... ... log4j.appender.Application.

我们的项目使用Log4J,通过Log4J.properties文件配置。我们有多个生产服务器,它们将日志记录到不同的日志文件,因此可以区分日志。节点1的log4j.properties如下所示:

...
log4j.appender.Application.File=D:/logs/application_1.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_1.log
...
...
log4j.appender.Application.File=${log.location}/application${log.file.postfix}.log
...
log4j.appender.tx_info.File=${log.location}/tx_info${log.file.postfix}.log
...
节点2的log4j.properties如下所示

...
log4j.appender.Application.File=D:/logs/application_2.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_2.log
...
我们已经使用Maven配置文件来生成服务器配置。到目前为止,它包含几个不同的log4j.properties文件,这些文件只在如上所示的日志文件名上有所不同。我想使用Maven使用以下资源模板文件生成这些文件:

...
log4j.appender.Application.File=D:/logs/application_1.log
...
log4j.appender.tx_info.File=D:/logs/tx_info_1.log
...
...
log4j.appender.Application.File=${log.location}/application${log.file.postfix}.log
...
log4j.appender.tx_info.File=${log.location}/tx_info${log.file.postfix}.log
...

使用不同的
${log.file.postfix}
值多次运行Maven很容易,每次都可以生成一个不同的日志属性文件。但是,我希望在一个构建中为每个服务器生成一个不同的属性文件(名称/路径不同)。我相当肯定这可以做到,例如通过antrun插件,但我不熟悉这一点。最简单的方法是什么?

以下是一些您可以尝试的方法:

  • 生成资源
    阶段,使用antrun插件和
    复制
    任务复制资源文件。关于这个问题的答案中给出了使用antrun插件的示例。您甚至可以使用ant的属性扩展将每个${log.file.postfix}扩展为一个不同的值,可以是文字值1、2、3等,也可以是唯一的占位符${log.file.postfix1}、${log.file.postfix2},当maven执行资源筛选时,这些占位符最终被替换

  • 使用版本控制系统设置同一文件的多个副本,而不是使用antrun。然后可以运行目标的多个实例,每个实例配置了不同的属性值和不同的目标文件名

  • (…)我相当肯定这是可以做到的,例如通过antrun插件,但我对此不熟悉。最简单的方法是什么

    您确实可以在POM中使用
    resources:copy resources
    和几个
    (注意
    resources:copy resources
    不允许更改目标文件的名称)

    假设您具有以下结构:

    $ tree .
    .
    ├── pom.xml
    └── src
        ├── main
        │   ├── filters
        │   │   ├── filter-node1.properties
        │   │   └── filter-node2.properties
        │   ├── java
        │   └── resources
        │       ├── log4j.properties
        │       └── another.xml
        └── test
            └── java
    
    其中
    log4j.properties
    使用占位符,而
    filter nodeN.properties
    文件包含这些值。例如:

    # filter-node1.properties
    
    log.location=D:/logs
    log.file.postfix=_1
    
    然后,在
    pom.xml
    中,配置资源插件,并为每个节点定义一个
    ,以调用
    copy resources
    ,使用特定的输出目录和特定的过滤器:

    <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>
    
    在每个
    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
    
    这有点可行,但很冗长,如果有相当数量的节点,这可能是个问题


    我试图使用Maven AntRun插件编写更简洁、更易维护的东西,但我无法从
    ant contrib
    获得
    for
    任务在Maven下工作(未知原因,
    for
    任务无法识别),于是我放弃了

    这里有一个使用Maven AntRun插件的替代方法。不复杂,没有循环,我只是将源文件复制到另一个位置,动态更改其名称并过滤内容:

      <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>
    


    但是,由于这些值似乎是节点特定的,<强>您是否考虑使用系统属性而不是< /强>(您可以放置在启动脚本中)?这是我已经做过的事情(使用

    log4j.xml
    ),它工作得很好,而且会大大简化事情。

    如果有很多目标配置需要复制,您可以将maven antrun插件与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>
    
    
    

    虽然这有点陈旧,但我最近遇到了这个线程,我想使用iterator maven插件提出一个更新的解决方案。概述如下:

    您如何实现目标的一个具体示例是将迭代器插件与一个复制资源和启用的过滤器结合起来。您甚至可以添加自定义属性文件以用作过滤器,以防使用此方法在每个节点上具有唯一的其他属性

    <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>
    
    
    com.soebes.maven.plugins
    迭代器maven插件
    0.3
    配置日志属性
    验证
    迭代器
    log.file.postfix
    1,2,3,4,5
    maven资源插件
    2.7
    复制资源
    ${project.build.directory}/nodes/${log.file.postfix}
    src/main/resources
    log4j.properties
    真的
    
    谢谢你的建议。使用资源:复制资源,难道不可能将同一个文件多次复制到具有不同属性的不同目标吗?但是,我不知道如何为不同的执行配置属性-您能给我举个具体的例子吗?您可以在pom中多次调用复制资源目标,每次都指定相同的源和不同的目标。我不知道复制资源是否允许重命名文件,但它允许设置目标目录。阳光明媚-我必须去花园里干活,但我会试着稍后把一些具体的东西放在一起。谢谢你的完整示例。这确实非常冗长——幸运的是w