ZetCode

Maven Build Phases

last modified June 9, 2025

In this article we show how to understand and use Maven build phases and lifecycle for effective Java project management.

What are Maven Build Phases?

Maven build phases are the individual steps in a build lifecycle that execute in a specific order. Each phase represents a stage in the build process, from validating the project to deploying the final artifact.

Phases are bound to goals, which are specific tasks that plugins perform. When you execute a phase, Maven runs all previous phases in the lifecycle automatically, ensuring a complete and consistent build process.

Understanding phases is crucial for effective Maven usage because they provide a standardized way to build, test, and deploy Java applications across different environments and teams.

Maven Build Lifecycles

Maven has three built-in build lifecycles, each serving a different purpose in the development process.

Default Lifecycle

The default lifecycle handles project deployment. It contains the most commonly used phases for building and testing your application.

Clean Lifecycle

The clean lifecycle removes artifacts created by previous builds. It ensures a clean state before building your project.

Site Lifecycle

The site lifecycle generates project documentation and reports. It creates websites with project information, test results, and code analysis.

Default Lifecycle Phases

The default lifecycle contains 23 phases, but here are the most important ones you'll use regularly:

validate

Validates that the project is correct and all necessary information is available. This phase checks the POM file structure and required properties.

$ mvn validate

compile

Compiles the source code of the project. The compiled classes are placed in the target/classes directory.

$ mvn compile

test

Runs unit tests using a suitable testing framework. Tests are not packaged or deployed during this phase.

$ mvn test

package

Takes the compiled code and packages it in its distributable format, such as a JAR or WAR file. The packaged file is created in the target directory.

$ mvn package

verify

Runs checks on the packaged code to verify it meets quality criteria. This may include integration tests and code quality checks.

$ mvn verify

install

Installs the package into the local repository, making it available as a dependency for other projects on the same machine.

$ mvn install

deploy

Copies the final package to a remote repository for sharing with other developers and projects. This is typically done in a CI/CD environment.

$ mvn deploy

Phase Execution Order

When you execute a specific phase, Maven automatically runs all preceding phases in the lifecycle. This ensures consistency and completeness.

Phase execution example
# Running package phase executes:
# validate → compile → test → package

$ mvn package

[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) ---
[INFO] --- maven-surefire-plugin:3.0.0:test (default-test) ---
[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) ---

Notice how Maven automatically executed the compile and test phases before creating the package, even though we only specified package.

Clean Lifecycle Phases

The clean lifecycle has three phases that help maintain a clean build environment.

pre-clean

Executes processes needed prior to the actual project cleaning. This phase is rarely used directly but can be customized with plugins.

clean

Removes all files generated by the previous builds. It deletes the target directory and its contents.

$ mvn clean

post-clean

Executes processes needed after the project cleaning. Like pre-clean, this is rarely used directly but available for customization.

Combining Lifecycles

You can combine phases from different lifecycles in a single command. This is commonly done to ensure a clean build.

$ mvn clean compile    # Clean then compile
$ mvn clean package    # Clean then package
$ mvn clean install    # Clean then install

The clean phase runs first, followed by the specified phase from the default lifecycle. This ensures no artifacts from previous builds interfere with the current build.

Skipping Phases

Sometimes you may want to skip certain phases during development. Maven provides properties to skip common phases.

Skipping Tests

To skip test compilation and execution:

$ mvn package -DskipTests         # Skip test execution
$ mvn package -Dmaven.test.skip   # Skip test compilation and execution

Skipping Specific Plugins

You can skip specific plugin executions using plugin-specific properties:

$ mvn package -Dcheckstyle.skip   # Skip Checkstyle plugin
$ mvn package -Dpmd.skip          # Skip PMD plugin

Phase Binding Example

Let's examine how phases are bound to plugin goals in a typical Maven project:

pom.xml - Plugin binding
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.11.0</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <phase>test</phase>
                    <goals>
                        <goal>test</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

This configuration shows how the compiler plugin's compile goal is bound to the compile phase, and the surefire plugin's test goal is bound to the test phase.

Custom Phase Execution

You can bind custom plugin goals to specific phases to extend the build process:

pom.xml - Custom phase binding
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>pre-compile-task</id>
                    <phase>process-sources</phase>
                    <configuration>
                        <target>
                            <echo message="Processing sources before compilation"/>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                
                <execution>
                    <id>post-package-task</id>
                    <phase>package</phase>
                    <configuration>
                        <target>
                            <echo message="Package created successfully"/>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

This example shows how to execute custom tasks during the process-sources and package phases using the AntRun plugin.

Viewing Phase Information

Maven provides several commands to help you understand phase execution and plugin bindings:

$ mvn help:describe -Dcmd=compile    # Describe compile phase
$ mvn help:effective-pom             # Show effective POM
$ mvn help:describe -Dplugin=compiler # Describe compiler plugin

These commands provide detailed information about what happens during specific phases and how plugins are configured.

Best Practices

Follow these best practices when working with Maven phases:

Always run mvn clean before important builds to ensure a clean state. Use mvn clean install for complete local builds that other projects can depend on.

Avoid skipping tests in production builds, but feel free to skip them during rapid development cycles. Use mvn compile for quick syntax checking during development.

Bind custom goals to appropriate phases based on when they should execute. Pre-processing tasks should bind to early phases, while post-processing tasks should bind to later phases.

Use mvn verify for comprehensive testing including integration tests, and mvn package when you only need the artifact without running integration tests.

Source

Maven Lifecycle Reference

In this article we have shown how to understand and use Maven build phases and lifecycle for effective Java project management.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Java tutorials.