Maven2 Build Lifecycle +
When you start building your large project with Maven2 it is not easy. You need to understand the concepts behind Maven2. One concept is the build lifecycle, which will be explained in this post.
Why is it important? I always call mvn clean install and everything is running.
For a simple project this is no problem, but in a real world project you need to know what is happening behind the scenes.
The default lifecycle consists of the following phases:
- validate
- compile
- test
- package
- integration-test
- verify
- install
- deploy
If you call mvn install in the default lifecycle, all phases until install will be running. Let’s step through the phases:
Validate: Check if all the pom.xml-Files in the project are valid and if all information for the build is available
Compile: Compile the source code, nothing special in here. For information where the compiled files are stored, check the default directory layout in Maven2.
Test: If nothing special is configured and you have stored your tests under src/test/java, the Surefire-Plugin will run your tests and generate reports
Package: If you are building a JAR, WAR, EAR or something else, it will be packaged in this phase. This is very important if you want to include sources into the package. Then you need choose a phase before the package phase is running.
Integration-Test: In this phase you can run your integration tests. Some phases have a pre- and post-phase, where you can prepare some things. We use it to start and end selenium to run our web tests in this phase. If you are testing something else, maybe Cargo then you will the pre- and post-phase useful to start and end your server(s).
Verify: Verify the generated package (I have never used this phase)
Install: This phase is important because the package (and its pom.xml) will be installed in the local repository. If there are dependencies to this project, it will be searched in the local repository.
Deploy: The deploy phase installs the package in the remote repository. In our environment this is the main proxy Archiva. Packages are build nightly in the CI-Server to be available for all developers. This phase could also be used, to deploy the hole project into a server.
Other phases:
You need to have a closer look at the phases if you need to generate (re)sources. To process our javascript (minify, verify with JSLint, …) we make heavy use of the following phases before the compile phase starts:
- generate-sources
- process-sources
- generate-resources
- process-resources
There are a lot of pre-configured goals defined for the lifecycle. Which goals are defined depends on the choosen packaging (JAR, WAR, EAR, …). You normally don’t need to know which goals are running, because they will fit to your packaging. If you need to hook into the lifecycle you configure your plugins to run in the appropriate phase. One the hand it is important to find the right phase that e.g. your resources are packaged, on the other hand we often try to find the phase which fits best to the concept of Maven2. This is important if other developers try to find out what is happening in the hole lifecycle.
We often use the AntRun-Plugin because it is a very easy way, to copy things, move things around or include tasks where you don’t want to write your own plugin. See an example for including this in your lifecycle:
...
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>Deploy .war</id>
<phase>install</phase>
<configuration>
<tasks>
<copy file="target/example.war"
tofile="${liferay_home}/deploy/example.war"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
In the next example you will see, how to start an integration test:
...
<build>
<finalName>ostium-mobile-suite</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>0.3-SNAPSHOT</version>
<configuration>
<wait>false</wait>
<container>
<containerId>tomcat5x</containerId>
<zipUrlInstaller>
<url>http://www.apache.org/dist/tomcat/tomcat-5/v5.5.16/bin/apache-tomcat-5.5.16.zip</url>
</zipUrlInstaller>
<output>${project.build.directory}/tomcat5x.log</output>
<log>${project.build.directory}/cargo.log</log>
</container>
<configuration>
<home>${project.build.directory}/tomcat5x/container</home>
<properties>
<cargo.logging>high</cargo.logging>
<cargo.servlet.port>8080</cargo.servlet.port>
<cargo.servlet.users>mobile:mobile:agent</cargo.servlet.users>
</properties>
</configuration>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
<configuration>
<deployer>
<deployables>
<deployable>
<groupId>agimatec</groupId>
<artifactId>mobile-suite</artifactId>
<type>war</type>
<pingURL>http://localhost:8080/ostium-mobile-suite/menu/index.action
</pingURL>
<pingTimeout>300000</pingTimeout>
<properties>
<context>ostium-mobile-suite</context>
</properties>
</deployable>
</deployables>
</deployer>
</configuration>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
To explore more details of the lifecycle phases read the Maven2 documentation.
I sometimes refer to http://cvs.peopleware.be/training/maven/maven2/buildLifecyclePhases.html about the maven lifecycle.