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. We'll be discussing Maven plugins in detail in Chapter 5, Maven Plugins.
In this chapter, the following topics will be covered:
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.
Maven comes with three standard lifecycles: default
, clean
, and site
. Each lifecycle defines its own set of phases.
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 that phase).
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:
$ 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 Version: 2.5 Goal Prefix: clean This plugin has 2 goals. clean:clean 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, project.build.outputDirectory, project.build.testOutputDirectory, andproject.reporting.outputDirectory.Files outside the default may also be included in the deletion by configuring the filesets tag. clean:help Description: Display help information on maven-clean-plugin.Call mvn clean:help -Ddetail=true -Dgoal=<goal-name> to display parameter details. For more information, run 'mvn help:describe [...] -Ddetail'
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:
$ 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 clea
n 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:
<plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>default-clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin>
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 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 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 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/maven-core/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/wso2/people/prabath/maven/chapter04/jose/.
$ 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-resources-plugin:2.6:resources * compile: org.apache.maven.plugins:maven-compiler-plugin: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:maven-resources-plugin:2.6:testResources * test-compile: org.apache.maven.plugins:maven-compiler-plugin: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-install-plugin:2.4:install * deploy: org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
The output lists out all the Maven plugins registered against different phases of the default
lifecycle for the jar
packaging. The jar
goal of maven-jar-plugin
is registered against the package
phase, while the install
goal of maven-install-plugin
is registered in the install
phase.
Let's run the previous command against a POM file having the war
packaging. It produces the following output:
It is a part of the lifecycle for the POM packaging 'war'. This life 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-resources-plugin:2.6:resources * compile: org.apache.maven.plugins:maven-compiler-plugin: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:maven-resources-plugin:2.6:testResources * test-compile: org.apache.maven.plugins:maven-compiler-plugin: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-war-plugin:2.2:war * pre-integration-test: Not defined * integration-test: Not defined * post-integration-test: Not defined * verify: Not defined * install: org.apache.maven.plugins:maven-install-plugin: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.
The site
lifecycle is defined with four phases: pre-site
, site
, post-site
, and site-deploy
. The site
lifecycle has no value without the Maven site
plugin. The site
plugin is used to generate static HTML content for a project. The generated HTML content will also include appropriate reports corresponding to the project. The site
plugin defines eight goals and two of them are directly associated with the phases in the site
lifecycle.
Let's run the following command against a POM file to describe the site goal:
$ mvn help:describe -Dcmd=site
As shown in the following output, the site
goal of the site
plugin is associated with the site
phase, while the deploy
goal of the site
plugin is associated with the site-deploy
phase:
[INFO] 'site' is a lifecycle with the following phases: * pre-site: Not defined * site: org.apache.maven.plugins:maven-site-plugin:3.3:site * post-site: Not defined * site-deploy: org.apache.maven.plugins:maven-site-plugin:3.3:deploy
The following figure shows the relationship between the Maven site plugin goals and the site
lifecycle phases:
3.133.133.233