maven之 build lifecycle
A Maven build lifecycle consists of a set of well-defined phases. Each phase groups a set of goals defined by Maven plugins and the lifecycle defines the order of execution. A Maven plugin is a collection of goals where each goal is responsible for performing a specific action.
The following figure shows the relationship between Maven plugin goals and lifecycle phases:
Let's take the simplest Maven build command that every Java developer is familiar with:
$ mvn clean install
What will this do? As a developer, how many times have you executed the previous command? Have you ever thought of what happens inside? If not, it's time to explore it now.
Standard lifecycles in Maven
Maven comes with three standard lifecycles: default, clean, and site. Each lifecycle defines its own set of phases.
The clean lifecycle
The clean lifecycle defines three phases: pre-clean, clean, and post-clean. A phase in a lifecycle is just an ordered placeholder in the build execution path.
For example, the clean phase in the clean lifecycle cannot do anything on its own. In the Maven architecture, it has two key elements: nouns and verbs. Both nouns and verbs, which are related to a given project, are defined in the POM file. The name of the project, the name of the parent project, the dependencies, and the type of the packaging are nouns. Plugins bring verbs into the Maven build system, and they define what needs to be done during the build execution via its goals. A plugin is a
group of goals. Each goal of a plugin can be executed on its own or can be registered as part of a phase in a Maven build lifecycle. When you type mvn clean, it executes all the phases defined in the clean lifecycle up to and including the clean phase. Don't be confused; in this command, clean is not the name of the lifecycle, it's the name of a phase. It's only a coincidence that
the name of the phase happens to be the name of the lifecycle. In Maven, you cannot simply execute a lifecycle by its name—it has to be the name of a phase. Maven will find the corresponding lifecycle and will execute it up to the given phase (including
When you type mvn clean, it cleans out project's working directory (by default, it's the target directory). This is done via the Maven clean plugin. To find more details about the Maven clean plugin, type the following command. It describes all the
goals defined inside the clean plugin:
Everything in Maven is a plugin. Even the command we executed previously to get goal details of the clean plugin executes another plugin: the help plugin. The following command will describe the help plugin itself:
<pre name="code" class="java">$ mvn help:describe -Dplugin=clean
Name: Maven Clean Plugin
Description: The Maven Clean Plugin is a plugin that removes files
generated at build-time in a project's directory.
Group Id: org.apache.maven.plugins
Artifact Id: maven-clean-plugin
Goal Prefix: clean
This plugin has 2 goals.
Description: Goal, which cleans the build. This attempts to clean a
project's working directory of the files that were generated at
build-time. By default, it discovers and deletes the directories
configured in project.build.directory,
andproject.reporting.outputDirectory.Files outside the default may
also be included in the deletion by configuring the filesets tag.
Description: Display help information on maven-clean-plugin.Call
mvn clean:help -Ddetail=true -Dgoal=<goal-name> to display parameter
For more information, run 'mvn help:describe [...] -Ddetail'
$ mvn help:describe -Dplugin=help
describe is a goal defined inside the help plugin.
The clean plugin has two goals defined in it: clean and help. As mentioned previously, each goal of a plugin can be executed on its own or can be registered as part of a phase in a Maven build lifecycle. A clean goal of the clean plugin
can be executed on its own with the following command:
$ mvn clean:clean
The following figure shows the relationship between the Maven clean plugin goals and the clean lifecycle phases:
The first clean word in the previous command is the prefix of the clean plugin, while the second one is the name of the goal. When you type mvn clean, it's the same clean goal that gets executed. However, this time it gets executed through the clean phase of the clean lifecycle, and it also executes all the phases in the corresponding lifecycle up to the clean phase—not just the clean phase. The clean goal of the clean plugin is configured by default to get executed during the clean lifecycle. The plugin goal to lifecycle phase mapping can be provided through the application POM file. If not, it will be inherited from the super POM file. The super POM file, which defines the clean plugin by default, adds the plugin to the clean phase of the clean lifecycle. You cannot define the same phase in two different lifecycles.
The following code snippet shows how the clean goal of the Maven clean plugin is associated with the clean phase of the clean lifecycle:
The pre-clean and post-clean phases of the clean lifecycle do not have any plugin bindings. The objective of the pre-clean phase is to perform any operations prior to the cleaning task and the objective of the post-clean phase is to perform
<pre name="code" class="java"><plugin>
any operations after the cleaning task. If you need to associate any plugins with these two phases, you simply need to add them to the corresponding plugin configuration.
The default lifecycle
The default lifecycle in Maven defines 23 phases. When you run the command mvn clean install, it will execute all the phases from the default lifecycle up to and including the install phase. To be precise, Maven will first execute all the phases in clean lifecycle up to and including the clean phase, and will then execute the default lifecycle up to and including the install phase.
The phases in the default lifecycle do not have any associated plugin goals. The plugin bindings for each phase are defined by the corresponding packaging. If the type of packaging of your Maven project is JAR, then it will define its own set of
plugins for each phase. If the packaging type is WAR, then it will have its own set of plugins. The following points summarize all the phases defined under the default lifecycle in their order of execution:
• validate: This phase validates the project POM file and makes sure all the necessary information related to carry out the build is available.
• initialize: This phase initializes the build by setting up the right directory structure and initializing properties.
• generate-sources: This phase generates any required source code.
• process-sources: This phase processes the generated source code.
For example, there can be a plugin running in this phase to filter the source code based on some defined criteria.
• generate-resources: This phase generates any resources that need to be packaged with the final artifact.
• process-resources: This phase processes the generated resources. It copies the resources to their destination directories and makes them ready for packaging.
• compile: This phase compiles the source code.
• process-classes: This phase can be used to carry out any bytecode enhancements after the compile phase.
• generate-test-sources: This phase generates the required source code for tests.
• process-test-sources: This phase processes the generated test source code. For example, there can be a plugin running in this phase to filter the source code based on some defined criteria.
• generate-test-resources: This phase generates all the resources required to run tests.
• process-test-resources: This phase processes the generated test resources. It copies the resources to their destination directories and makes them ready for testing.
• test-compile: This phase compiles the source code for tests.
• process-test-classes: This phase can be used to carry out any bytecode enhancements after the test-compile phase.
• test: This phase executes tests using the appropriate unit test framework.
• prepare-package: This phase is useful in organizing the artifacts to be packaged.
• package: This phase packs the artifacts into a distributable format, for example, JAR or WAR.
• pre-integration-test: This phase performs the actions required (if any) before running integration tests. This may be used to start any external application servers and deploy the artifacts into different test environments.
• integration-test: This phase runs integration tests.
• post-integration-test: This phase can be used to perform any cleanup tasks after running the integration tests.
• verify: This phase verifies the validity of the package. The criteria to check the validity needs to be defined by the respective plugins.
• install: This phase installs the final artifact in the local repository.
• deploy: This phase deploys the final artifact to a remote repository.
The packaging type of a given Maven project is defined under the <packaging> element in the pom.xml file. If the element is omitted, then Maven assumes it as jar packaging
The following figure shows all the phases defined under the Maven default lifecycle and their order of execution:
More details about Maven lifecycles can be found at http://maven.apache.org/ref/3.2.3/mavencore/lifecycles.html.
Let's have a look at a concrete example. Run the following command against a Maven project having the jar packaging. If you do not have such a project you can download a sample Maven project from https://svn.wso2.org/repos/
$ mvn help:describe -Dcmd=deploy
Here we are using the Maven help plugin to find more details about the deploy phase corresponding to the jar packaging, and it will produce the following output:
It is a part of the lifecycle for the POM packaging 'jar'. This lifecycle
includes the following phases:
* validate: Not defined
* initialize: Not defined
* generate-sources: Not defined
* process-sources: Not defined
* generate-resources: Not defined
* process-resources: org.apache.maven.plugins:maven-resourcesplugin:2.6:resources
* compile: org.apache.maven.plugins:maven-compilerplugin:2.5.1:compile
* process-classes: Not defined
* generate-test-sources: Not defined
* process-test-sources: Not defined
* generate-test-resources: Not defined
* process-test-resources: org.apache.maven.plugins:mavenresources-plugin:2.6:testResources
* test-compile: org.apache.maven.plugins:maven-compilerplugin:2.5.1:testCompile
* process-test-classes: Not defined
* test: org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
* prepare-package: Not defined
* package: org.apache.maven.plugins:maven-jar-plugin:2.4:jar
* pre-integration-test: Not defined
* integration-test: Not defined
* post-integration-test: Not defined
* verify: Not defined
* install: org.apache.maven.plugins:maven-installplugin:2.4:install
* deploy: org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
Now if you look at the package phase, you will notice that we have a different plugin goal: maven-war-plugin.
Similarly to the jar and war packaging, each of the other packaging type defines its own bindings for the default lifecycle.
Mastering Apache Maven 3
Copyright © 2014 Packt Publishing