eclipse – 如何在maven构建期间覆盖WAR文件中的文件?

我有一个Java webapp项目,我在Eclipse(更准确地说是MyEclipse 10)中开发并使用Maven 3构建.

我有以下布局(仅包括与我的问题相关的文件:

project root
|-- src
|   |-- main
|   |   |-- java
|   |   |-- resources
|   |   |   |-- log4j.xml
|   |   |   +-- struts.properties
|   |   |-- webapp
|   |   |   |-- META-INF
|   |   |   |   +--context.xml
|   |   |-- config
|   |   |   |-- test
|   |   |   |   |--log4j.xml
|   |   |   |   |--struts.properties
|   |   |   |   +--context.xml
|   |   |   +-- prod
|   |   |   |   |--log4j.xml
|   |   |   |   |--struts.properties
|   |   |   |   +--context.xml
|   +--test
+--pom.xml

如您所见,我包含了许多配置文件.在项目结构中处于适当位置的人,即在src / main / resources和src / main / webapp中,是我在MyEclipse中工作时经常使用的那些.我可以使用MyEclipse连接器自动将部署更新到例如我的开发机器上的Tomcat实例.我只需点击“运行服务器”即可调试.实际上,在这种情况下根本不需要使用Maven.

然后,当我想为另一个环境(如测试或生产)构建一个版本时,我运行mvn -P test clean install并构建一​​个很好的WAR.

我的目标是用src / config / {environment} /中的那些替换最终WAR中的配置文件.

我在我的pom.xml中设置了配置文件:

<profiles>
    <profile>
        <id>test</id>
        <properties>
            <environment>test</environment>
        </properties>
    </profile>

    <profile>
        <id>prod</id>
        <properties>
            <environment>prod</environment>
        </properties>
    </profile>
</profiles>

然后,我尝试将这些资源从指定的配置文件(使用环境变量)复制到WAR内部的正确位置(或将压缩到WAR中的临时文件夹):

<webResources>
    <resource>
        <directory>/src/main/config/${environment}</directory>
        <targetPath>META-INF/</targetPath>
        <includes>
            <include>context.xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/config/${environment}</directory>
        <targetPath>WEB-INF/classes/</targetPath>
        <includes>
            <include>
                struts.properties
            </include>
            <include>
                log4j.xml
            </include>
        </includes>
    </resource>
</webResources>

现在这似乎有效,除了“标准”资源被复制到此后的目录,因此它们会覆盖这些文件.所以我总是最终得到来自src / main / resources的log4j.xml而不是来自src / main / configuration / prod /的log4j.xml

从Maven输出中提取:

[INFO] Processing war project
[INFO] Copying webapp webResources [D:\workspace\MyProject/src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna]
[INFO] Copying webapp webResources [D:\workspace\MyProject\src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna]
[INFO] Copying webapp resources [D:\workspace\MyProject\src\main\webapp]

正如你在最后一行看到的那样,来自src / main / webapp的东西被复制了AFTER,从而覆盖了我的自定义文件:(

我的问题:如何强制Maven使用“来自激活的配置文件”的文件,并以某种方式OVERWRITE“自然”文件?

最佳答案
正如第二个Q/A given by user944849所指出的,最简单的解决方案是过滤掉原始文件,以便它们可以被配置文件文件夹中的文件替换.

所以我添加了对标准资源的过滤:

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <!-- Exclude those since they are copied from the profile folder for the build -->
                <exclude>log4j.xml</exclude>
                <exclude>struts.properties</exclude>
            </excludes>
            <filtering>false</filtering>
        </resource>
    </resources>

而对于网络资源:

<warSourceExcludes>**/context.xml</warSourceExcludes>

所以现在3个文件没有复制到WAR文件夹中.在下一步(webResources)中,它们将从活动配置文件的文件夹中复制.

我还添加了一个默认文件夹,其中包含具有常用值的3个文件.此默认文件夹中的文件也会被复制,但只能在配置文件的文件夹之后复制.由于资源未被覆盖,因此只有在资源尚不存在时才会复制它们.如果您在未激活配置文件的情况下进行构建,或者您可以定义合理的默认值,则无论每个配置文件是否相同,都不需要复制该文件.

配置文件夹的结构:

-- config
   |-- test
   |   |--log4j.xml
   |   |   |--struts.properties
   |   |   +--context.xml
   |   +-- prod
   |   |   |--log4j.xml
   |   |   +--context.xml
   |   +-- default
   |       |--log4j.xml
   |       |--struts.properties
   |       +--context.xml
...

和我的pom.xml的webResources部分:

<webResources>
    <!-- Resources from the activated profile folder -->
    <resource>
        <directory>/src/main/config/${environment}</directory>
        <targetPath>META-INF/</targetPath>
        <includes>
            <include>context.xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/config/${environment}</directory>
        <targetPath>WEB-INF/classes/</targetPath>
        <includes>
            <include>
                struts.properties
            </include>
            <include>
                log4j.xml
            </include>
        </includes>
    </resource>
    <!-- Default resources in case some file was not defined in the profile folder -->
    <!-- Files are not overwritten so default files will be copied only if it does not exist already -->
    <resource>
        <directory>/src/main/config/default</directory>
        <targetPath>META-INF/</targetPath>
        <includes>
            <include>context.xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/config/default</directory>
        <targetPath>WEB-INF/classes/</targetPath>
        <includes>
            <include>
                struts.properties
            </include>
            <include>
                log4j.xml
            </include>
        </includes>
    </resource> 
</webResources>

转载注明原文:eclipse – 如何在maven构建期间覆盖WAR文件中的文件? - 代码日志