Maven models projects as nouns which are described by a POM. The POM captures the identity of a project: What does a project contain? What type of packaging a project needs? Does the project have a parent? What are the dependencies? We've explored the idea of describing a project in the previous chapters, but we haven't introduced the mechanism that allows Maven to act upon these objects. In Maven the "verbs" are goals packaged in Maven plugins which are tied to a phases in a build lifecycle. A Maven lifecycle consists of a sequence of named phases: prepare-resources, compile, package, and install among other. There is phase that captures compilation and a phase that captures packaging. There are pre- and post- phases which can be used to register goals which must run prior to compilation, or tasks which must be run after a particular phase. When you tell Maven to build a project, you are telling Maven to step through a defined sequence of phases and execute any goals which may have been registered with each phase.
A build lifecycle is an organized sequence of phases that exist to give order to a set of goals. Those goals are chosen and bound by the packaging type of the project being acted upon. There are three standard lifecycles in Maven: clean, default (sometimes called build) and site. In this chapter, you are going to learn how Maven ties goals to lifecycle phases and how the lifecycle can be customized. You will also learn about the default lifecycle phases.
The first lifecycle you'll be interested in is the simplest lifecycle in Maven. Running mvn clean invokes the clean lifecycle which consists of three lifecycle phases:
-
pre-clean -
clean -
post-clean
The interesting phase in the clean lifecycle is the
clean phase. The Clean plugin's clean goal
(clean:clean) is bound to the
clean phase in the clean
lifecycle. The clean:clean goal deletes the output of
a build by deleting the build directory. If you haven't customized the
location of the build directory it will be the
${basedir}/target directory as defined by the Super
POM. When you execute the
clean:clean goal you do not do so by executing the
goal directly with mvn clean:clean, you do so by
executing the clean phase of the clean lifecycle.
Executing the clean phase gives Maven an opportunity
to execute any other goals which may be bound to the
pre-clean phase.
For example, suppose you wanted to trigger an
antrun:run goal task to echo a notification on
pre-clean, or to make an archive of a project's build
directory before it is deleted. Simply running the
clean:clean goal will not execute the lifecycle at
all, but specifying the clean phase will use the
clean lifecycle and advance through the three
lifecycle phases until it reaches the clean phase.
Example 10.1, “Triggering a Goal on pre-clean” shows an example of build
configuration which binds the antrun:run goal to the
pre-clean phase to echo an alert that the project
artifact is about to be deleted. In this example, the
antrun:run goal is being used to execute some
arbitrary Ant commands to check for an existing project artifact. If the
project's artifact is about to be deleted it will print this to the
screen
Example 10.1. Triggering a Goal on pre-clean
<project>
...
<build>
<plugins>... <plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>file-exists</id>
<phase>pre-clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- adds the ant-contrib tasks (if/then/else used below) -->
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<available
file="${project.build.directory}/${project.build.finalName}.${project.packaging}"
property="file.exists" value="true" />
<if>
<not>
<isset property="file.exists" />
</not>
<then>
<echo>No
${project.build.finalName}.${project.packaging} to
delete</echo>
</then>
<else>
<echo>Deleting
${project.build.finalName}.${project.packaging}</echo>
</else>
</if>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Running mvn clean on a project with this build configuration will produce output similar to the following:
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------
[INFO] Building Your Project
[INFO] task-segment: [clean]
[INFO] ----------------------------------------------------------------------
[INFO] [antrun:run {execution: file-exists}]
[INFO] Executing tasks
[echo] Deleting your-project-1.0-SNAPSHOT.jar
[INFO] Executed tasks
[INFO] [clean:clean]
[INFO] Deleting directory ~/corp/your-project/target
[INFO] Deleting directory ~/corp/your-project/target/classes
[INFO] Deleting directory ~/corp/your-project/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Nov 08 11:46:26 CST 2006
[INFO] Final Memory: 2M/5M
[INFO] ------------------------------------------------------------------------
In addition to configuring Maven to run a goal during the
pre-clean phase, you can also customize the Clean plugin to
delete files in addition to the build output directory. You can
configure the plugin to remove specific files in a
fileSet. The example below configures clean to remove
all .class files in a directory named
target-other/ using standard Ant file wildcards:
* and **.
Example 10.2. Customizing Behavior of the Clean Plugin
<project>
<modelVersion>4.0.0</modelVersion>
...
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>target-other</directory>
<includes>
<include>*.class</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</project>Most Maven users will be familiar with the default lifecycle. It
is a general model of a build process for a software application. The
first phase is validate and the last phase is
deploy. The phases in the default Maven lifecycle are
shown in Table 10.1, “Maven Lifecycle Phases”.
Table 10.1. Maven Lifecycle Phases
| Lifecycle Phase | Description |
|---|---|
| validate | Validate the project is correct and all necessary information is available to complete a build |
| generate-sources | Generate any source code for inclusion in compilation |
| process-sources | Process the source code, for example to filter any values |
| generate-resources | Generate resources for inclusion in the package |
| process-resources | Copy and process the resources into the destination directory, ready for packaging |
| compile | Compile the source code of the project |
| process-classes | Post-process the generated files from compilation, for example to do bytecode enhancement on Java classes |
| generate-test-sources | Generate any test source code for inclusion in compilation |
| process-test-sources | Process the test source code, for example to filter any values |
| generate-test-resources | Create resources for testing |
| process-test-resources | Copy and process the resources into the test destination directory |
| test-compile | Compile the test source code into the test destination directory |
| test | Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed |
| prepare-package | Perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package (coming in Maven 2.1+) |
| package | Take the compiled code and package it in its distributable format, such as a JAR, WAR, or EAR |
| pre-integration-test | Perform actions required before integration tests are executed. This may involve things such as setting up the required environment |
| integration-test | Process and deploy the package if necessary into an environment where integration tests can be run |
| post-integration-test | Perform actions required after integration tests have been executed. This may include cleaning up the environment |
| verify | Run any checks to verify the package is valid and meets quality criteria |
| install | Install the package into the local repository, for use as a dependency in other projects locally |
| deploy | Copies the final package to the remote repository for sharing with other developers and projects (usually only relevant during a formal release) |
Maven does more than build software artifacts from project, it can also generate project documentation and reports about the project, or a collection of projects. Project documentation and site generation have a dedicated lifecycle which contains four phases:
-
pre-site
-
site
-
post-site
-
site-deploy
The default goals bound to the site lifecycle is:
-
site - site:site
-
site-deploy -site:deploy
The packaging type does not usually alter this lifecycle since packaging types are concerned primarily with artifact creation, not with the type of site generated. The Site plugin kicks off the execution of Doxia document generation and other report generation plugins. You can generate a site from a Maven project by running the following command:
$ mvn site
For more information about Maven Site generation, see Chapter 15, Site Generation.

