3.5.2. Maven Lifecycle

The second command we ran in the previous section was mvn install. This command didn’t specify a plugin goal; instead, it specified a Maven lifecycle phase. A phase is a step in what Maven calls the “build lifecycle.” The build lifecycle is an ordered sequence of phases involved in building a project. Maven can support a number of different lifecycles, but the one that’s most often used is the default Maven lifecycle, which begins with a phase to validate the basic integrity of the project and ends with a phase that involves deploying a project to production. Lifecycle phases are intentionally vague, defined solely as validation, testing, or deployment, and they may mean different things to different projects. For example, in a project that produces a Java archive, the package phase produces a JAR; in a project that produces a web application, the package phase produces a WAR.

Plugin goals can be attached to a lifecycle phase. As Maven moves through the phases in a lifecycle, it will execute the goals attached to each particular phase. Each phase may have zero or more goals bound to it. In the previous section, when you ran mvn install, you might have noticed that more than one goal was executed. Examine the output after running mvn install and take note of the various goals that are executed. When this simple example reached the package phase, it executed the jar goal in the Jar plugin. Since our simple Quickstart project has (by default) a jar packaging type, the jar:jar goal is bound to the package phase.

A Goal Binds to a Phase

Figure 3.2. A Goal Binds to a Phase


We know that the package phase is going to create a JAR file for a project with jar packaging. But what of the goals preceding it, such as compiler:compile and surefire:test? These goals are executed as Maven steps through the phases preceding package in the Maven lifecycle; executing a phase will first execute all preceding phases in order, ending with the phase specified on the command line. Each phase corresponds to zero or more goals, and since we haven’t performed any plugin configuration or customization, this example binds a set of standard plugin goals to the default lifecycle. The following goals are executed in order when Maven walks through the default lifecycle ending with package:

resources:resources

The resources goal of the Resources plugin is bound to the process-resources phase. This goal copies all of the resources from src/main/resources and any other configured resource directories to the output directory.

compiler:compile

The compile goal of the Compiler plugin is bound to the compile phase. This goal compiles all of the source code from src/main/java or any other configured source directories to the output directory.

resources:testResources

The testResources goal of the Resources plugin is bound to the process-test-resources phase. This goal copies all of the resources from src/test/resources and any other configured test resource directories to a test output directory.

compiler:testCompile

The testCompile goal of the Compiler plugin is bound to the test-compile phase. This goal compiles test cases from src/test/java and any other configured test source directories to a test output directory.

surefire:test

The test goal of the Surefire plugin is bound to the test phase. This goal executes all of the tests and creates output files that capture detailed results. By default, this goal will terminate a build if there is a test failure.

jar:jar

The jar goal of the Jar plugin is bound to the package phase. This goal packages the output directory into a JAR file.

Bound Goals are Run when Their Phases Execute

Figure 3.3. Bound Goals are Run when Their Phases Execute


To summarize, when we executed mvn install, Maven executes all phases up to the install phase, and in the process of stepping through the lifecycle phases it executes all goals bound to each phase. Instead of executing a Maven lifecycle goal you could achieve the same results by specifying a sequence of plugin goals as follows:

mvn resources:resources \
    compiler:compile \
    resources:testResources \
    compiler:testCompile \
    surefire:test \
    jar:jar \
    install:install 

It is much easier to execute lifecycle phases than it is to specify explicit goals on the command line, and the common lifecycle allows every project that uses Maven to adhere to a well-defined set of standards. The lifecycle is what allows a developer to jump from one Maven project to another without having to know very much about the details of each particular project's build. If you can build one Maven project, you can build them all.