skip to content

Plugins & Goals

The plugin subsystem end to end: how plugins are resolved, configured, bound to phases, and written from scratch. Interviewers dig here because in Maven everything that actually happens is a plugin goal.

on this pageshow

explore

questions

page 1 of 2

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

open as a page

What does the <configuration> block do inside a Maven plugin declaration, and how do you pass parameters to a plugin?

level: juniorimportance: must knowfreq 70%

basics

~20 s

The <configuration> block sets a plugin's parameters in the pom.xml. Each child element name matches a plugin parameter (for example <source>17</source> for the compiler), and Maven injects those values into the plugin Mojo when it runs.

open as a page

What are Maven's core build plugins, and what is each one responsible for during a build?

level: juniorimportance: must knowfreq 70%

basics

~20 s

Core build plugins handle the standard build steps: clean removes target/, resources copies non-code files, jar packages a JAR, install copies the artifact to the local repository, and deploy uploads it to a remote repository.

open as a page

What is a Maven plugin, and how does it relate to a 'goal' (mojo)?

level: juniorimportance: must knowfreq 80%

basics

~20 s

A Maven plugin is a bundle of related tasks. Each task is a 'goal', implemented by a class called a mojo. You run a goal like mvn compiler:compile, where compiler is the plugin and compile is the goal.

open as a page

What is a Mojo in Maven, and what are the minimum pieces you write to create a custom plugin goal?

level: middleimportance: must knowfreq 55%

basics

~10 s

A Mojo is the Java class behind one Maven goal. You extend AbstractMojo, annotate the class with @Mojo(name = "..."), implement execute(), and package it as a maven-plugin artifact so Maven can run it.

open as a page

How do you expose configuration to a Mojo, and how does a user set those values from the POM or command line?

level: middleimportance: must knowfreq 50%

basics

~10 s

You annotate fields with @Parameter. Users set them in the plugin's <configuration> block in the POM using the field name as the XML element, or via -D using the parameter's property name.

open as a page

What is the difference between configuring <release> and <source>/<target> in the maven-compiler-plugin, and which should you prefer today?

level: middleimportance: must knowfreq 75%

basics

~10 s

<source>/<target> set the language level and bytecode version separately. <release> sets both at once AND links against that JDK's API, preventing accidental use of newer APIs. Prefer <release>.

open as a page

Explain the <executions> element: what do id, phase, goals, and a per-execution <configuration> control?

level: middleimportance: must knowfreq 75%

basics

~10 s

An <execution> binds a plugin's goal(s) to a lifecycle phase. <id> names it, <phase> says when it runs, <goals> lists which goals to run, and an execution-scoped <configuration> sets parameters only for that execution.

open as a page

How does the <packaging> value determine which plugin goals are bound to lifecycle phases by default?

level: middleimportance: must knowfreq 60%

basics

~10 s

The packaging type selects a default set of goal-to-phase bindings. For example jar binds jar:jar at package, while pom binds almost nothing and war binds war:war instead.

open as a page

How do you uniquely identify a Maven plugin, and what is special about the org.apache.maven.plugins groupId?

level: middleimportance: must knowfreq 70%

basics

~10 s

A plugin is identified by coordinates groupId:artifactId:version, just like a dependency. The groupId org.apache.maven.plugins is the default Maven assumes for core plugins, so you can sometimes omit it.

open as a page

What is <pluginManagement> and why pin plugin versions there instead of declaring them in <plugins>?

level: seniorimportance: must knowfreq 65%

basics

~20 s

<pluginManagement> declares plugin versions and default config in a parent POM without actually enabling the plugin. Child modules that list the plugin (by groupId/artifactId, no version) inherit the pinned version and config, giving consistent, reproducible builds.

open as a page

How does Maven know what goals a plugin offers, and how do you bind a goal to a lifecycle phase?

level: juniorimportance: should knowfreq 30%

basics

~20 s

The plugin ships a descriptor file, META-INF/maven/plugin.xml, generated from your @Mojo/@Parameter annotations by the maven-plugin-plugin. To bind a goal to a phase, set defaultPhase on @Mojo or add an <execution> with a <phase> in the consumer POM.

open as a page

What does the -parameters compiler flag do, and which frameworks rely on it?

level: middleimportance: should knowfreq 45%

basics

~10 s

-parameters tells javac to keep real method parameter names in the bytecode. Without it, names become arg0, arg1. Frameworks like Spring MVC and JPA queries use them via reflection.

open as a page

What does the -proc / proc:none compiler option control, and when would you disable annotation processing?

level: middleimportance: should knowfreq 40%

basics

~10 s

The -proc flag controls whether javac runs annotation processing. proc:none compiles without running any processors; proc:only runs processors but skips compilation. Disable processing to speed builds or avoid unwanted code generation.

open as a page

What is the difference between plugin-level configuration and execution-scoped configuration, and what does the <inherited> flag do?

level: middleimportance: should knowfreq 30%

basics

~10 s

Plugin-level <configuration> applies to all the plugin's goals/executions and to direct CLI calls; execution-scoped config applies only to that execution. The <inherited>false</inherited> flag stops a plugin or execution from being inherited by child modules.

open as a page

How does maven-resources-plugin work, and what does resource filtering do?

level: middleimportance: should knowfreq 45%

basics

~10 s

maven-resources-plugin copies files from src/main/resources into target/classes. With filtering enabled, it replaces ${...} placeholders in those files with property values during the copy.

open as a page

What are Maven build extensions, and how do they differ from plugins?

level: middleimportance: should knowfreq 45%

basics

~10 s

Extensions are add-ons that plug into Maven's core to add capabilities like new packaging types, lifecycles, or transport protocols. Unlike plugins, which run goals during a build, extensions participate in how Maven itself works.

open as a page

How do you configure a plugin and bind specific goals to run, including multiple separate runs of the same plugin?

level: middleimportance: should knowfreq 55%

basics

~10 s

Set parameters in the plugin's <configuration> block. To run goals at build time, add <executions>: each <execution> lists <goals>, an optional <phase>, an <id>, and its own <configuration>. Multiple executions = multiple runs.

open as a page

How do you write integration tests for a Maven plugin, and what role does the maven-invoker-plugin play?

level: seniorimportance: should knowfreq 28%

basics

~20 s

Unit tests check the Mojo class in isolation, but integration tests run the plugin inside a real Maven build. The maven-invoker-plugin executes small sample projects under src/it/, runs goals against your freshly-installed plugin, and verifies the results.

open as a page

What does requiresDependencyResolution on a Mojo do, and when would you need it?

level: seniorimportance: should knowfreq 35%

basics

~20 s

It tells Maven to resolve the project's dependencies (for a given scope) before running the Mojo, so the Mojo can read the resolved artifacts/classpath. You need it whenever your goal inspects or uses the project's dependencies.

open as a page

How do you configure annotation processors in the maven-compiler-plugin, and why is annotationProcessorPaths preferred over putting processors on the classpath?

level: seniorimportance: should knowfreq 55%

basics

~10 s

Use <annotationProcessorPaths> to list processor artifacts (like Lombok or MapStruct) separately from your project dependencies. This keeps processors off the runtime/compile classpath while still running them during compilation.

open as a page

How do combine.children and combine.self control how a child POM's plugin configuration merges with an inherited one?

level: seniorimportance: should knowfreq 35%

basics

~20 s

By default Maven merges inherited and child plugin config, appending list items. The combine.children attribute controls list merging (merge vs append), and combine.self controls whether the child element merges with, overrides, or removes the parent's element.

open as a page

Walk through what maven-deploy-plugin does at the deploy phase, and how SNAPSHOT versions are handled differently from releases.

level: seniorimportance: should knowfreq 40%

basics

~10 s

deploy uploads the artifact and POM to a remote repository. SNAPSHOT versions go to the snapshots repo and can be re-deployed (overwritten with timestamps); release versions go to the releases repo and are immutable.

open as a page

How does a build extension contribute a custom packaging type and lifecycle mapping?

level: seniorimportance: should knowfreq 35%

basics

~10 s

An extension ships component metadata that registers a new <packaging> value and maps which plugin goals run in each lifecycle phase. You then set extensions=true on the plugin and use that packaging.

open as a page

What is a Maven wagon, and how do you add support for a repository protocol Maven doesn't ship?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A wagon is Maven's transport provider for talking to a repository over a given protocol (http, scp, ftp). To use a protocol Maven doesn't ship, you add the matching wagon as a build/core extension so the protocol's URLs resolve.

open as a page

How does Maven resolve a short goal prefix like 'help' or 'spring-boot' to an actual plugin artifact?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Maven looks up the prefix in maven-metadata.xml files stored under each configured plugin group in the repositories. That metadata maps a prefix (e.g. help) to a plugin artifactId, so prefix:goal can be resolved to a real plugin.

open as a page

Why should core plugin versions be pinned and managed centrally, and how do you do it across a multi-module build?

level: principalimportance: should knowfreq 35%

basics

~10 s

If you don't pin core plugin versions, Maven picks defaults that can change between Maven releases, making builds non-reproducible. Pin them in <pluginManagement> in a parent POM so every module uses the same versions.

open as a page

What is the maven-site-plugin for, and when would you still use it today?

level: juniorimportance: nice to knowfreq 15%

basics

~10 s

maven-site-plugin generates a static HTML website for a project, including reports like javadoc, test results, and dependency info. It runs on the separate site lifecycle via mvn site.

open as a page

What is polyglot Maven and what does it require to work?

level: middleimportance: nice to knowfreq 15%

basics

~20 s

Polyglot Maven lets you write the build model in formats other than XML — like YAML, Groovy, Kotlin, or Atom — instead of pom.xml. It works by installing a core extension that parses the alternative format.

open as a page

When and why would you fork the compiler with meminitial/maxmem, and how does the plugin's incremental compilation work?

level: seniorimportance: nice to knowfreq 30%

basics

~10 s

Set <fork>true</fork> to run javac in a separate JVM, then size it with <meminitial> and <maxmem> for big modules. Incremental compilation (the default) only recompiles changed/stale classes instead of everything.

open as a page

showing 1–30 of 32