Maven Lifecycle, Goals, and Phases

3 minute read

When you run mvn package, Maven doesn’t just package — it executes a sequence of phases leading up to package. Understanding this lifecycle is key to using Maven effectively.


Three Built-In Lifecycles

Lifecycle Purpose Key Phases
default Build and deploy compile, test, package, install, deploy
clean Remove build output clean
site Generate documentation site, site-deploy

Default Lifecycle Phases

validate  →  Does the project have a valid POM?
compile   →  Compile src/main/java → target/classes
test      →  Run unit tests (Surefire plugin)
package   →  Create JAR/WAR in target/
verify    →  Run integration tests and checks
install   →  Copy artifact to ~/.m2/repository
deploy    →  Upload to remote repository (Nexus/Artifactory)

Phases are sequential. Running mvn package automatically runs validate → compile → test → package.


Running Maven

# Compile source code
mvn compile

# Compile + run tests
mvn test

# Compile + test + create JAR
mvn package

# Compile + test + package + install to local repo
mvn install

# Delete target/ directory
mvn clean

# Clean + package (most common)
mvn clean package

# Clean + install
mvn clean install

Terminal Output

$ mvn clean package

[INFO] --- clean:3.3.2:clean (default-clean) @ my-project ---
[INFO] Deleting /Users/dev/my-project/target

[INFO] --- compiler:3.13.0:compile (default-compile) @ my-project ---
[INFO] Compiling 15 source files to target/classes

[INFO] --- surefire:3.2.5:test (default-test) @ my-project ---
[INFO] Tests run: 42, Failures: 0, Errors: 0, Skipped: 0

[INFO] --- jar:3.4.1:jar (default-jar) @ my-project ---
[INFO] Building jar: target/my-project-1.0.0.jar

[INFO] BUILD SUCCESS
[INFO] Total time:  8.234 s

Goals vs Phases

Concept Definition Example
Phase Step in a lifecycle compile, test, package
Goal Specific task from a plugin compiler:compile, surefire:test

Plugins bind goals to phases:

compile phase  ←  compiler:compile goal
test phase     ←  surefire:test goal
package phase  ←  jar:jar goal

You can run goals directly:

mvn compiler:compile       # just compile, skip validation
mvn surefire:test          # just test, skip compile (uses existing classes)
mvn dependency:tree        # not tied to any phase

Skipping Tests

# Skip test execution (still compiles tests)
mvn package -DskipTests

# Skip test compilation AND execution
mvn package -Dmaven.test.skip=true

In pom.xml:

<properties>
    <skipTests>true</skipTests>  <!-- Not recommended permanently -->
</properties>

The target/ Directory

target/
├── classes/                    ← Compiled main classes
├── test-classes/               ← Compiled test classes
├── surefire-reports/           ← Test results (XML + TXT)
├── maven-status/               ← Build metadata
├── my-project-1.0.0.jar       ← Final artifact
└── maven-archiver/
    └── pom.properties

target/ is always safe to delete — mvn clean does exactly this.


Lifecycle Visualization

mvn clean package
     │       │
     │       └──→ default lifecycle: validate → compile → test → package
     │
     └──────────→ clean lifecycle: clean
mvn clean install
     │       │
     │       └──→ validate → compile → test → package → verify → install
     │
     └──────────→ clean

Multiple Phases and Goals

# Run clean lifecycle, then default up to install
mvn clean install

# Run a specific goal + a phase
mvn dependency:tree package

# Multiple goals
mvn compiler:compile surefire:test

Profiles — Environment-Specific Builds

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <env>development</env>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <env>production</env>
            <skipTests>false</skipTests>
        </properties>
    </profile>
</profiles>
mvn clean package -Pprod

Common Mistakes

Mistake Fix
Running mvn deploy locally deploy uploads to remote repo — use install for local
Thinking mvn test doesn’t compile It does — every phase runs all prior phases
Committing target/ to Git Add target/ to .gitignore
Always skipping tests Fix the tests instead

Key Takeaways

  1. Maven has three lifecycles: default, clean, site.
  2. Phases are sequential — mvn package runs validate → compile → test → package.
  3. Goals are tasks from plugins; phases are lifecycle steps.
  4. mvn clean package is the most common command — clean first, then build.
  5. target/ is generated — never edit it, always safe to delete.

What’s Next?

Next: Maven Dependency Management — scopes, transitive dependencies, BOMs, and the dependency tree.

Updated: