skip to content

Where in the build lifecycle does the maven-compiler-plugin run, and which goals does it execute by default?

level: juniorimportance: must knowfreq 60%

answer

  1. compile goal → compile phase
  2. testCompile goal → test-compile phase
  3. auto-bound by jar packaging
  4. target/classes vs target/test-classes
  5. add plugin only to configure

basics

~10 s

The compiler plugin's compiler:compile goal binds to the compile phase (main sources) and compiler:testCompile binds to test-compile (test sources). Maven binds these automatically for jar projects.

solid answer

~30 s

For a standard packaging like jar, Maven's default lifecycle bindings attach `maven-compiler-plugin:compile` to the `compile` phase and `maven-compiler-plugin:testCompile` to the `test-compile` phase. So when you run `mvn package`, Maven walks the phases up to package, and compilation of `src/main/java` happens at compile, then `src/main/test` (test sources) compiles at test-compile before tests run. You normally never declare these executions yourself — they come with the packaging. You only add the plugin to the `<build><plugins>` section to override its `<configuration>` (release, parameters, processor paths). The compile goal puts classes in `target/classes`; testCompile in `target/test-classes`.

code

bash · 5 lines
bash
# default bindings fire automatically:
mvn compile        # runs compiler:compile -> target/classes
mvn test           # also runs compiler:testCompile -> target/test-classes
# or invoke a goal directly:
mvn compiler:compile

go deeper

for a junior

Knows compile runs at the compile phase and tests compile at test-compile automatically.

for a middle

Knows the goals (compile/testCompile), default bindings, and output directories.

for a senior

Understands the lifecycle ordering and that plugin-level configuration applies to both default executions.

for a principal

Manages compiler config centrally in a parent POM's pluginManagement so all modules inherit consistent bindings and settings.

## Lifecycle, phases, goals Maven's **default lifecycle** is an ordered list of **phases**: ...`validate` → `compile` → `test-compile` → `test` → `package`... Running a phase runs every phase before it. A **plugin goal** (the actual unit of work) is *bound* to a phase. ## What the compiler plugin binds to For `jar` (and similar) packaging, Maven's built-in bindings automatically attach: - `maven-compiler-plugin:compile` → the **`compile`** phase — compiles `src/main/java` into `target/classes`. - `maven-compiler-plugin:testCompile` → the **`test-compile`** phase — compiles `src/test/java` into `target/test-classes`, with the test + main classpath. Because these are part of the packaging's default bindings, **you do not write `<executions>` for them**. Running `mvn compile`, `mvn test`, or `mvn package` triggers them in order. ## You only configure, not bind You add the plugin to override behaviour: ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <release>21</release> <parameters>true</parameters> </configuration> </plugin> </plugins> </build> ``` This configuration applies to both default executions (compile + testCompile) since it sits at plugin level. ## Running goals directly You can also invoke a goal ad hoc: ```bash mvn compiler:compile mvn compiler:testCompile ``` but in practice you run phases (`mvn compile`, `mvn test`) and let the bindings fire. ## Outputs - main → `target/classes` - test → `target/test-classes` These become the classpath roots downstream (test, package).

  • Do you need to declare <executions> for compile and testCompile?
    No. They are part of the default lifecycle bindings for jar/war packaging; you add the plugin only to override configuration.
  • Where do compiled main and test classes go?
    Main sources compile to target/classes; test sources to target/test-classes.

saying these in an interview costs you the question

  • Claiming you must manually bind compile/testCompile executions.
  • Confusing the compile phase (main) with test-compile (tests).
  • Thinking the plugin compiles during package — compilation already happened at the earlier compile/test-compile phases.

context