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



我有一个Java Web应用程序项目,我在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/resourcessrc/main/webapp,是我在MyEclipse中工作时经常使用的人。我可以使用MyEclipse连接器自动更新部署,例如我的开发机器上的Tomcat实例。我只需点击"运行服务器",就可以调试了。实际上,在这种情况下根本不需要使用Maven。

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

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

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

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

然后,我尝试将这些资源从指定的概要文件(使用environment变量)复制到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/resourceslog4j.xml,而不是来自src/main/configuration/prod/

Maven输出摘录:

[INFO] Processing war project
[INFO] Copying webapp webResources [D:workspaceMyProject/src/main/config/prod] to [D:workspacesSITELWebfaunatargetWebfauna]
[INFO] Copying webapp webResources [D:workspaceMyProjectsrc/main/config/prod] to [D:workspacesSITELWebfaunatargetWebfauna]
[INFO] Copying webapp resources [D:workspaceMyProjectsrcmainwebapp]

正如您在最后一行中所看到的,src/main/webapp中的内容在AFTER之后被复制,从而覆盖了我的自定义文件:(

我的问题是:如何强制Maven使用"来自激活的概要文件"的文件,并以某种方式重写"自然"文件?

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

看看这些问题/答案中的任何一个。一个可能对你有用。

在war打包之前,在maven构建阶段运行ant任务?

在maven项目中构建战争时文件被覆盖

另一次尝试:)

我玩过overlay参数。我认为这只会替换你在webapp文件夹中的另一个war文件中的webapp文件夹内的文件。所以这对你的设置来说并不是一件完美的事情。

然而,上面提到的webResource参数可以做到这一点:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mimacom.maven.examples</groupId>
<artifactId>mimacom-war-overlays</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>${project.artifactId}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.compiler.version>1.6</project.build.compiler.version>
<junit.version>4.9</junit.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>${project.build.compiler.version}</source>
<target>${project.build.compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>src/main/config/prod</directory>
</resource>
</webResources>
<!--<includes>-->
<!--<include>${basedir}/environments/overlay-1/css/styles.css</include>-->
<!--</includes>-->
<!--<overlays>-->
<!--<overlay>-->
<!--<includes>-->
<!--../environments/overlay-1/css/**-->
<!--</includes>-->
<!--</overlay>-->
<!--</overlays>-->
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>src/main/config/test</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

激活的配置文件将向war文件添加其他文件夹。所以,这应该奏效!

我看到您将使用相同的资源,但在每个配置文件(测试和生产)中使用不同的配置。

所以,我建议你使用这样的配置:

<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>env</name>
<name>test</name>
</property>
</activation>
<build>
<filters>
<filter>test.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>prod</value>
</property>
</activation>
<build>
<filters>
<filter>prod.properties</filter>
</filters>
</build>
</profile>
</profiles>

在这个场景中,我有两个配置文件,每个配置文件都使用"env"参数激活。每个概要文件都有一个文件来过滤资源,将log4j.xml、struts.properties、context.xml文件放在src/main/resources中,并使用变量在每个概要文件中使用正确的配置。

希望能有所帮助。

我认为您需要覆盖war文件。要么在每个war类型的概要文件中创建一个依赖项,而不是jar,这将覆盖当前war文件中的文件。

另一种可能是maven war插件的覆盖配置。

因此配置文件会激活您想要复制的文件,而不是当前的文件。插件网站上有相当多的文档,还有一些示例

希望能奏效!

这里是上面解决方案的一个更简单的版本,它只依赖于插入到pom.xml中的一个简单片段。

使用构建默认(本地工作站)网络应用程序

mvn war:exploded

添加一个环境命令行参数,将文件从特定于环境的目录(如resources prod)复制到目标WEB-INF/classes目录:

mvn war:exploded -Denvironment=prod

将其添加到pom.xml的项目元素中:

<!-- this profile will allow files in environment-specific folders like resources-prod or resources-test
to be added to the resulting war's classpath under WEB-INF/classes
to activate the profile, simply add '-Denvironment=prod' to your maven build command 
this also works fine with war:inplace and war:exploded 
-->
<profile>
<id>environment-specific</id>
<activation>
<property>
<name>environment</name>
</property>
</activation>
<build>
<plugins>   
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<!-- note the order of the following resource elements are important. 
if there are duplicate files, the first file copied will win
-->
<resource>
<!-- this is relative to the pom.xml directory -->                        
<directory>resources-${environment}</directory>
<!-- override default destination at root of war -->
<targetPath>WEB-INF/classes</targetPath>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>             
</plugins>
</build>
</profile>

更多信息和工作示例链接。

相关内容

  • 没有找到相关文章

最新更新