我有一个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/resources
和src/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/resources
的log4j.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>
更多信息和工作示例链接。