skip to content

How would you disable or override an inherited goal binding (e.g., skip the default jar or surefire execution) coming from packaging or a parent POM?

level: principalimportance: should knowfreq 30%

answer

  1. phase>none = unbind
  2. match the inherited id
  3. default-<goal> ids
  4. skipTests vs maven.test.skip
  5. merge-by-id is the mechanism

basics

~10 s

Redeclare the plugin and its execution by the same id and set <phase>none</phase> to unbind it, or use the plugin's skip flag (e.g., -DskipTests / <skip>true</skip>). For default packaging executions, target the id 'default-<goal>'.

solid answer

~40 s

There are two levers. (1) **Unbind an execution**: redeclare the same plugin and an `<execution>` with the matching `<id>` and set `<phase>none</phase>`. Default bindings from packaging have well-known ids like `default-jar`, `default-test`, `default-compile`; redeclaring `default-jar` with phase `none` stops the jar from being built. Parent-POM executions are overridden the same way by matching their id. (2) **Skip via configuration**: many plugins expose a skip parameter — `surefire` has `<skipTests>`/`-DskipTests` and `<skip>`, `jar` and others vary. Skipping leaves the binding in place but makes the goal a no-op. Prefer `phase>none` when you genuinely want the goal removed, and the skip flag for conditional/profile-driven cases. The id-merge rule is what makes this work: same id merges, so your redeclaration overrides the inherited one rather than adding a duplicate.

code

xml · 11 lines
xml
<!-- Stop a module from building its jar (override packaging default) -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <id>default-jar</id>
      <phase>none</phase>
    </execution>
  </executions>
</plugin>

go deeper

for a junior

Know -DskipTests skips running tests.

for a middle

Use a plugin's <skip> config and know skipTests vs maven.test.skip.

for a senior

Apply phase>none with the correct default-<goal> id to truly unbind an inherited goal.

for a principal

Design parent POMs with stable execution ids so overrides are predictable, and choose skip-vs-unbind deliberately across a large module tree.

## Why you'd override a binding A module inherits bindings from its packaging and from parent POMs. Sometimes you need to suppress one — e.g., a module that should not produce a jar, or one where you want to relocate tests to a different phase. ## Lever 1: phase 'none' (unbind by id) The canonical trick: redeclare the plugin, match the inherited execution's `<id>`, and set `<phase>none</phase>` (any unknown/non-phase value works, but `none` is the convention). Because executions merge by id, this **overrides** the inherited binding and detaches the goal from the lifecycle. Default, packaging-supplied executions have predictable ids of the form `default-<goal>`: - `default-jar` (jar:jar) - `default-compile` / `default-testCompile` - `default-test` (surefire:test) - `default-resources` / `default-testResources` - `default-install`, `default-deploy` ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <executions> <execution> <id>default-jar</id> <!-- matches the packaging default --> <phase>none</phase> <!-- unbind it: no jar produced --> </execution> </executions> </plugin> ``` ## Lever 2: skip flags (no-op the goal) Many plugins offer a skip parameter, keeping the binding but doing nothing: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration><skipTests>true</skipTests></configuration> </plugin> ``` or on the CLI: `mvn install -DskipTests` (compiles tests but doesn't run) vs `-Dmaven.test.skip=true` (also skips compiling tests). Note these are plugin-specific; not every goal has a skip. ## Lever 3: override config / relocate You can also keep the goal but change its phase or configuration by redeclaring the same id with a new `<phase>` and `<configuration>`. This is how a parent's binding gets repointed in a child. ## Choosing - **Remove permanently for this module** -> `phase>none`. - **Conditionally / per-environment** -> skip flag, ideally toggled via a profile property. - **Keep but change when/how it runs** -> redeclare same id with new phase/config. ## Governance angle In a large reactor, design parent-POM executions with stable, documented ids so children can override predictably. Undocumented or duplicated ids make overrides brittle — a child that uses the wrong id ends up *adding* a second execution instead of suppressing the inherited one.

  • What is the difference between -DskipTests and -Dmaven.test.skip=true?
    -DskipTests compiles test sources but skips running them (surefire/failsafe). -Dmaven.test.skip=true also skips compiling the test sources entirely.
  • Why must you match the inherited execution's id to disable it?
    Executions merge by id during inheritance. A matching id overrides the inherited binding; a different id just adds another execution, leaving the original active.
  • What are the ids of packaging-default executions?
    They follow default-<goal>, e.g. default-jar, default-compile, default-test, default-install.

saying these in an interview costs you the question

  • Adding a new execution with a fresh id and expecting it to suppress the inherited one (it adds, not removes)
  • Assuming every plugin has a skip flag
  • Confusing skipTests (skip running) with maven.test.skip (skip compile + run)
  • Thinking you can delete an inherited binding without redeclaring its plugin/id

context