skip to content

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%

answer

  1. plugin-level vs execution-level config
  2. execution = id + goals + phase + config
  3. execution config merges over plugin config
  4. run same plugin twice via two executions
  5. phase none disables inherited execution

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.

solid answer

~40 s

A plugin entry in <build><plugins> can carry a top-level <configuration> that applies to all of its executions, plus an <executions> list. Each <execution> has an <id> (unique per plugin), a set of <goals>, an optional <phase> to bind them to (overriding or supplementing the goal's default phase), and an optional execution-level <configuration> that overrides the plugin-level one for that run. This lets you run the same plugin several times with different settings — e.g. the maven-antrun-plugin or build-helper twice in different phases. Goals that already have a default phase binding (because they declare @phase in the mojo or via the packaging's default lifecycle) don't need an explicit <phase>. Execution-level config is merged with plugin-level config, with execution values winning. You can disable an inherited execution by re-declaring its id with <phase>none</phase>.

code

xml · 15 lines
xml
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>3.6.0</version>
  <executions>
    <execution>
      <id>add-integration-source</id>
      <phase>generate-sources</phase>
      <goals><goal>add-source</goal></goals>
      <configuration>
        <sources><source>src/it/java</source></sources>
      </configuration>
    </execution>
  </executions>
</plugin>

go deeper

for a junior

Knows you set plugin options in a <configuration> block.

for a middle

Knows executions bind goals to phases, with ids and per-execution config, and that a plugin can run multiple times.

for a senior

Uses execution-level overrides, disables inherited executions with phase none, and reasons about config merging.

for a principal

Designs parent-pom plugin configuration with inherited/combine semantics so teams override cleanly without copy-paste.

## Two levels of configuration ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.13.0</version> <configuration> <release>21</release> <!-- applies to ALL executions --> </configuration> <executions> <execution> <id>compile-preview</id> <phase>compile</phase> <goals><goal>compile</goal></goals> <configuration> <compilerArgs><arg>--enable-preview</arg></compilerArgs> </configuration> </execution> </executions> </plugin> ``` - **Plugin-level `<configuration>`** is the default for every execution and for direct CLI invocation of the plugin's goals. - **Execution-level `<configuration>`** applies only to that one execution and is *merged* over the plugin-level one (execution wins on conflicts). ## Executions: binding goals to phases An `<execution>` answers three questions: *which goals*, *in which phase*, *with what id*. - `<id>` must be unique within the plugin; it identifies the execution in logs (`compiler:compile (compile-preview)`) and lets child poms override or disable it. - `<goals>` lists one or more goals to run in this execution. - `<phase>` binds them into the lifecycle. If omitted, the goal's *default phase* (declared in the mojo via `@Mojo(defaultPhase=...)`) is used. Some goals have no default phase and must be given one. ## Running a plugin twice Because each execution is independent, you can run the same plugin multiple times with different ids/phases/configs — common with `build-helper-maven-plugin`, `maven-antrun-plugin`, or running `maven-failsafe-plugin` for different test groups. ## Default vs. explicit executions Goals already bound by the packaging's default lifecycle (e.g. `compiler:compile` in the `compile` phase for a `jar` project) run *without* you writing an execution — those are the implicit `default-*` executions. Adding `<executions>` supplements or, by reusing the id `default-compile`, overrides them. ## Disabling an inherited execution To turn off an execution inherited from a parent pom, redeclare it with the same `<id>` and set `<phase>none</phase>`: ```xml <execution> <id>default-test</id> <phase>none</phase> </execution> ``` ## inherited and combine attributes `<plugin inherited="false">` stops child poms from inheriting it. The `combine.children`/`combine.self` attributes on configuration elements control list merging vs. replacement during inheritance.

  • How do you run the same plugin twice with different settings?
    Add two <execution> entries with distinct <id>s, each with its own <phase> and <configuration>.
  • What happens if a goal has no default phase and you omit <phase>?
    It won't be bound to the lifecycle, so it only runs if invoked directly; you must specify a phase to wire it into a build.
  • How do you disable an execution inherited from a parent pom?
    Redeclare the same <id> and set <phase>none</phase>.

saying these in an interview costs you the question

  • Thinking <configuration> at plugin level only affects CLI runs — it also seeds every execution.
  • Believing you can only run a plugin once per build.
  • Forgetting that execution <id> must be unique and is how overrides/disables target an execution.

context