63

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?

default locale
  • 13,035
  • 13
  • 56
  • 62
Adrian Pronk
  • 13,486
  • 7
  • 36
  • 60
  • 1
    The war file still get created, so what? Why is that a problem? – Pascal Thivent Sep 19 '09 at 23:27
  • 6
    I assume it's because they want to speed up the build -- at least that's why I'm using this. I have a basic spring application with maven, but I'm working with Google App Engine, which is configured to scan the exploded war build directory, so for me to see changes, I need to build the exploded war -- often. Any way to invoke this automatically any times any files in the project are changed? – chrismarx Feb 13 '12 at 00:34

5 Answers5

82

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>
Michael Wyraz
  • 3,638
  • 1
  • 27
  • 25
  • 7
    This is the simplest and easiest solution posted here. – Ajax Sep 28 '12 at 13:56
  • Yes, this seems to be the best answer. Worked like a charm for me. :) – Joshua Davis Jul 23 '13 at 15:00
  • 3
    Can you explain for me how this works? Where did you learn that to disable default phase-goal binding is done using id "default-war"? – Matt Warrick Aug 04 '13 at 13:42
  • Great solution - took me one or two go-arounds to fully understand it and get it to work. – Dave G Sep 12 '13 at 10:26
  • @LiborJelinek The way I've gotten IDs is to use 'mvn help:effective-pom' This will show you everything that's running including the IDs of each execution – Roy Truelove Sep 14 '15 at 17:33
  • I start getting following error after this `The packaging for this project did not assign a file to the build artifact -> [Help 1]` . How to solve this? – Shashwat Kumar Feb 14 '17 at 03:11
  • 1
    +1. is it the `default-warnone` that actually eliminated creation of a war ? because without it and with the other execution, the war still got created? thanks in advance – amphibient Jul 05 '17 at 20:35
  • also, please consider this question: https://stackoverflow.com/questions/44935759/how-to-make-war-from-exploded-directory – amphibient Jul 05 '17 at 20:51
50

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.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
cetnar
  • 9,357
  • 2
  • 38
  • 45
  • 1
    If you really like this, you can put the war:exploded invocation into the pom bound to the prepare-package phase. But you will have a problem if you ever need maven to go ahead and run the rest of the phases, so switching to <packaging>pom is better. – bmargulies Aug 15 '10 at 12:35
  • I found this failed on mine because its trying to do a FileInputStream.open on the 'classes' folder. However running as two seperate commands worked `mvn prepare-package` and then `mvn war:exploded` ah maven you mysterious beast – JonnyRaa Apr 02 '15 at 10:20
  • 1
    this doesn't work if you have a project split into several jars - they will need to be `install`ed to get them into maven's static cache for them to picked up in the prepare-package stage. – JonnyRaa Apr 07 '15 at 14:26
10

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.

David
  • 1,920
  • 25
  • 31
  • 1
    If install fails it is correct because nothing installed, but this is fakely pretend it is done. Probably it is better making profile for exploded and war packaging where exploded profile fails for install correctly. – Daniel Hári Sep 21 '16 at 10:01
6

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-->
Community
  • 1
  • 1
Rich Seller
  • 83,208
  • 23
  • 172
  • 177
0

As far as I know (I'm still new to maven) this is not possible. The only default lifecycle you can skip is 'test'. In order to get to the deploy you have to package. You can read all about the default lifecycle order of execution here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference

l15a
  • 2,547
  • 5
  • 29
  • 41