skip to content

On the mvn command line, what is the difference between passing a lifecycle phase (like `mvn package`) and a direct plugin goal (like `mvn compiler:compile`)?

level: juniorimportance: must knowfreq 80%

answer

  1. phase runs up to and including
  2. goal = prefix:goal, runs alone
  3. left-to-right execution
  4. clean package = two lifecycles
  5. phases do nothing without bound goals

basics

~10 s

A phase (e.g. package) runs every step bound to it and all earlier phases in order. A goal (e.g. compiler:compile) runs just that one plugin task by itself.

solid answer

~40 s

Maven's command line accepts two kinds of arguments. A lifecycle phase like `package` is a named stage; running it executes all phases up to and including it (validate → compile → test → package), and at each phase Maven runs the plugin goals bound to it. A direct goal is written `prefix:goal` (e.g. `compiler:compile`) or fully as `groupId:artifactId[:version]:goal`; it runs exactly that one goal and nothing else — no preceding phases. You normally invoke phases for the standard build flow and invoke a single goal ad hoc (e.g. `mvn dependency:tree`, `mvn help:effective-pom`). You can also mix them on one line: `mvn clean package` runs the clean phase then the default-lifecycle build, and arguments execute left to right.

code

bash · 9 lines
bash
# Phase: runs validate->compile->test->package
mvn package

# Direct goal: runs ONLY this goal, nothing before it
mvn compiler:compile
mvn dependency:tree

# Mixed, executed left to right
mvn clean install

go deeper

for a junior

Know that a phase runs everything up to it; a goal is one task.

for a middle

Explain goal binding to phases and prefix:goal vs fully-qualified syntax.

for a senior

Reason about left-to-right execution, mixing lifecycles, and when ad-hoc goals are appropriate vs full builds.

for a principal

Govern plugin prefix/group configuration and standardize which goals teams run vs CI phases.

## The two argument types Maven (`mvn`) is a build tool driven by the **build lifecycle** — an ordered, fixed sequence of stages called **phases**. The command line lets you pass either phases or plugin goals, and understanding the difference is foundational. ### Lifecycle phases The default lifecycle has phases in this fixed order (abbreviated): `validate` → `compile` → `test-compile` → `test` → `package` → `verify` → `install` → `deploy`. There are two other lifecycles: **clean** (`pre-clean`, `clean`, `post-clean`) and **site** (`pre-site`, `site`, ...). When you run `mvn package`, Maven runs **every phase from the start of that lifecycle up to and including** `package`. So it validates, compiles, runs tests, then packages. This is why `mvn test` also compiles first — it can't run tests without compiling. Phases by themselves do nothing; work happens because **plugin goals are bound to phases**. For a `jar` packaging project, `compiler:compile` is bound to `compile`, `surefire:test` to `test`, `jar:jar` to `package`, and so on. ### Plugin goals (direct invocation) A **goal** is a single unit of work in a **plugin**. You invoke one directly using the form: ``` mvn <prefix>:<goal> e.g. mvn dependency:tree mvn <groupId>:<artifactId>:<version>:<goal> (fully qualified) ``` Direct goal invocation runs **only that goal** — Maven does NOT run any preceding phases. `mvn compiler:compile` compiles but does not validate or run tests. The short `prefix` (e.g. `dependency`, `help`, `compiler`) is resolved via plugin metadata; standard Apache plugins (`maven-*-plugin`) get a prefix automatically. ### Mixing and ordering Arguments execute **left to right**. `mvn clean package` runs the `clean` phase (deletes `target/`) then builds through `package`. `mvn clean compiler:compile flatten:flatten` would run clean, then a single goal, then another single goal. ## When to use which - **Phases**: normal builds — `mvn verify`, `mvn install`, `mvn clean package`. - **Direct goals**: one-off diagnostics or tasks not in the normal flow — `mvn help:effective-pom`, `mvn dependency:tree`, `mvn versions:display-dependency-updates`. ## Key elements - Lifecycles: default, clean, site - Phase binding configured in `<build><plugins>` via `<executions>` - Plugin prefix resolution (`maven-dependency-plugin` → `dependency`)

  • Does `mvn test` compile your code first?
    Yes. `test` is a later phase, so Maven runs validate, compile, test-compile, then test — all preceding default-lifecycle phases.
  • How does Maven turn the short prefix `dependency` into the real plugin?
    Via plugin prefix resolution: it checks the plugin's `META-INF/maven/plugin.xml` goalPrefix and configured plugin groups in settings.xml; Apache `maven-*-plugin` artifacts get an automatic prefix.

A phase is like 'cook dinner' — it implies all prior steps (shop, prep, cook). A goal is like 'just chop the onions' — one isolated task you can do on its own.

saying these in an interview costs you the question

  • Saying `mvn compiler:compile` also runs tests or earlier phases — direct goals run alone.
  • Claiming `clean` is part of the default lifecycle (it's a separate lifecycle).
  • Thinking phases contain logic themselves rather than being binding points for plugin goals.

context