How to get Maven to run war:exploded but not war:war

I have a Maven pom that uses <packaging>war</packaging>. But actually, I don't want build the war-file, I just want all the dependent jars collected and a full deployment directory created.

So I'm running the war:exploded goal to generate the deploy directory:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <webappDirectory>target/${env}/deploy</webappDirectory>
                <archiveClasses>true</archiveClasses>
            </configuration>
            <goals>
                <goal>exploded</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The trouble is, the war file still gets built. Is there a simple way of having <packaging>war</packaging> execute the war:exploded goal instead of the war:war goal?

Or is there another simple way to do this?


Solution 1:

The solution is quite simple. You need to override the default execution of the war plugin to disable it and add your own execution (for exploded):

<pluginManagement>
    <plugins>
            <plugin><!-- don't pack the war  -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-war</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>war-exploded</id>
                        <phase>package</phase>
                        <goals>
                            <goal>exploded</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    </plugins>
</pluginManagement>

Solution 2:

According builtin lifecycle bindings for war packaging in package phase war:war mojo is called.

You can call previous 'prepare-package' phase - all actions will be performed and after that call mojo war:exploded

mvn prepare-package war:exploded

The results will be the same as yours but no war created.

Solution 3:

I would like to upgrade onto @Michael Wyraz answer and just include install skip settings in case if someone executes mvn clean install build on top level of multimodule project and one of sub-module is web application.

This stands inside war module:

<profiles>
    <profile>
        <id>war_explode</id>
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.6</version>
                        <executions>
                            <execution>
                                <id>default-war</id>
                                <phase>none</phase>
                            </execution>
                            <execution>
                                <id>war-exploded</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>exploded</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-install-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>default-install</id>
                                <phase>none</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </profile>
</profiles>

Without install skip build fails as it tries to install war into .m2 folder. Error message looks like this:

[INFO] --- maven-install-plugin:2.4:install (default-install) @ *** ---
[INFO]   ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project ***: The packaging for this project did not assign a file to the build artifact -> [Help 1]

Executing mvn clean install -P war_explode with this settings (enclosed in maven profile named war_explode) it finishes build without error.

Solution 4:

The only way I can think of to do what you want is to set use pom packaging (or create a custom packaging) and bind the required goals from the war packaging to the relevant phases of the lifecycle. If you go for pom packaging you can use define the war:war execution in a profile to allow you to package it, but you'll need to use the build-helper-maven-plugin attach-artifact goal to attach the war to the pom.

Note with this approach if you want to use any other war-specific processing it may cause you problems.

The lifecycle bindings for war packaging are listed in the Introduction to The Build Lifecycle (see the "Default Lifecycle Bindings - Packaging ejb / ejb3 / jar / par / rar / war" section).

To bind the relevant plugin executions to the pom packaging you would do as follows:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
          <id>process-resources</id>
          <phase>process-resources</phase>
          <goals>
            <goal>resources</goal>
          </goal>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-compile-plugin</artifactId>
      <executions>
        <execution>
          <id>compile</id>
          <phase>compile</phase>
          <goals>
            <goal>compile</goal>
          </goal>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
          <id>process-test-resources</id>
          <phase>process-test-resources</phase>
          <goals>
            <goal>testResources</goal>
          </goal>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <executions>
        <execution>
          <id>test</id>
          <phase>test</phase>
          <goals>
            <goal>test</goal>
          </goal>
        </execution>
      </executions>
    </plugin>
    <!-- package not wanted, install and deploy already defined for pom packaging-->
    <!--define war:war execution in a profile in case it is needed-->