开发者

How do I get Maven 2 to build 2 separate WAR files

When doing a mvn install I want to end up with 2 WAR files in my target directory. One will contain the production web.xml and the other will contain the test/uat web.xml.

I've tried this:

<build>开发者_开发问答
    <finalName>cas-server</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1-beta-1</version>
            <configuration>
                <webXml>src/main/config/prod/web.xml</webXml>
                <warName>cas-prod</warName>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1-beta-1</version>
            <configuration>
                <webXml>src/main/config/test/web.xml</webXml>
                <warName>cas-test</warName>
            </configuration>
        </plugin>
    </plugins>
</build>

But I only end up with the test WAR.


I don't think you can do this in one step (actually, I'm surprised that Maven doesn't complain about your setup and wonder which one is applied) and I'd suggest to use profiles and maybe filtering to manage this use case.

If your web.xml are really different, you could just put your maven-war-plugin configuration in two profiles. Or, better, you could merge them into something like this:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.1-beta-1</version>
  <configuration>
    <webXml>src/main/config/${env}/web.xml</webXml>
    <warName>cas-test</warName>
  </configuration>
</plugin>

And set the env property in two profiles to pick up the right web.xml at build time.

<profiles>
  <profile>
    <id>uat</id>
    <properties>
      <env>test</env>
    </properties>
  </profile>
  <profile>
    <id>prod</id>
    <properties>
      <env>prod</env>
    </properties>
  </profile>
</profiles>

If your web.xml are similar (i.e. if only values differ in them), you could define properties and their values in two profiles and use filtering to apply them. Something like this:

<profiles>
  <profile>
    <id>env-uat</id>
    <activation>
      <property>
        <name>env</name>
        <value>uat</value>
      </property>
    </activation>
    <properties>
      <key1>uat_value_key_1</key1>
      <keyN>uat_value_key_n</keyN>
    </properties>
  </profile>
  <profile>
    <id>env-prod</id>
    <activation>
      <property>
        <name>env</name>
        <value>prod</value>
      </property>
    </activation>  
    <properties>
      <key1>prod_value_key_1</key1>
      <keyN>prod_value_key_n</keyN>
    </properties>
  </profile>
</profiles>

Then activate one profile or the other by passing the env property on the command line, e.g.:

mvn -Denv=uat package

Another option would be to put the values into specific filters and pick up the right one at build time (like in this post).

There are really many options but as I said, I don't think you can do this without runngin the build twice.

More resources on profiles/filtering:

  • Maven Book: Chapter 11. Build Profiles
  • Maven Book: Chapter 15.3. Resource Filtering
  • Introduction to Build Profiles
  • Use an alternative Maven Profile during test phase
  • maven profile filtering search on Google


You can tell the Maven Assembly plugin to simply generate two assemblies. You just write an assembly descriptor file for each output you wish to create and list them in the plugin config.

For example I'm using it to generate a WAR file and a TGZ file, but there's no reason you can't do two WARs in the same way. mvn package will then generate both files.

        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <descriptors>
                    <descriptor>src/main/assembly/assembly-war.xml</descriptor>
                    <descriptor>src/main/assembly/assembly-dist.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <id>dist-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>


I'd generally suggest to use profiles and run two dedicated builds. However, it should be possible to create any number of artifacts using the maven-assembly-plugin.


Old Question, but I want to answer for completeness.

You can do this in one build step very simply with the war plugin with two executions. See the sample code below:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <executions>
                <execution>
                    <id>build-context-one</id>
                    <phase>install</phase>
                    <goals>
                        <goal>war</goal>
                    </goals>
                    <configuration>
                        <classifier>context-one</classifier>
                        <webResources>
                            <resource>
                                <filtering>true</filtering>
                                <directory>src/main/webapp</directory>
                                <includes>
                                    <include>**</include>
                                </includes>
                            </resource>
                            <resource>
                                <directory>your-context-one-directory</directory>
                            </resource>
                        </webResources>
                    </configuration>
                </execution>
                <execution>
                    <id>build-context-two</id>
                    <phase>install</phase>
                    <goals>
                        <goal>war</goal>
                    </goals>
                    <configuration>
                        <classifier>classifier-two</classifier>
                        <webResources>
                            <resource>
                                <filtering>true</filtering>
                                <directory>src/main/webapp</directory>
                                <includes>
                                    <include>**</include>
                                </includes>
                            </resource>
                            <resource>
                                <directory>your-context-two-directory</directory>
                            </resource>
                        </webResources>
                    </configuration>
                </execution>
            </executions>


I think this can only be achieved by writing a custom Maven plugin or interfering with the build lifecycle and running the war assembling process twice (this is just a faint idea).

Maybe you could create two profiles and run the goal twice with different profiles (mvn -P prof1 package, mvn -P prof2 package), but be careful with the generated artifact names, they shouldn't be overwritten. Or you might be able to create a custom plugin that uses other plugins and assembles the two war files.


While I don't use Maven but Ivy instead, here's how you should generally do this:

Have your own application published in to a private repository/similar as JAR with its dependencies/other static stuff and then individual project settings for building the application's deployment specific WARs with context specific configurations. Now by building any of the individual deployment projects you get the latest version of your actual application with its build specific configurations.

I would assume that since this is trivial in Ivy, Maven should be able to do it just as easily.


Sort-of-ugly hack (it breaks Maven's idea of declaring intentions instead of actions), but worked for me: I had to generate two wars which shared the same back-end code base, but varied on the MVC controller packages.

After banging my head with several plugins, I thought "hey, I'd do it easily in ant", which lead me to use <maven-antrun-plugin> to generate the wars during the "package" phase (on which we arlready have all the files). Sort of like this:

<plugin>
  <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>run</goal>
        </goals>
        <configuration>
          <tasks>  
            <delete file="target/war-1.war" />
            <delete file="target/war-2.war" />            
            <war destfile="target/war-1.war">
              <fileset dir="target/original">
                <exclude name="**/WEB-INF/classes/package_of_war2/**" />
              </fileset>
            </war>
            <war destfile="target/war-2.war">
              <fileset dir="target/original">
                <exclude name="**/WEB-INF/classes/package_of_war1/**" />
              </fileset>
            </war>
            <delete file="target/original.war" /
          </tasks>
        </configuration>
      </execution>
    </executions>
  </plugin>

(to be fair, I did not delete the original file, but you should be able to do so.)

In your case, you could package one war without the alternate web.xml, rename/move it over the original web.xml, then package the second war.


More simple:

Just create a multi modules project.

Each module would have the WAR packaging :)

Build from parent pom and voila !

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜