skip to content

Build Extensions

Build <extensions> and core extensions in .mvn/extensions.xml, which can contribute packaging types, lifecycles, and repository transports before the build begins. A niche question that reveals how deeply you have bent Maven.

on this pageshow

explore

questions

5

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

level: middleimportance: should knowfreq 45%

answer

  1. plugins = goals; extensions = machinery
  2. .mvn/extensions.xml loads before pom
  3. packaging + lifecycle + wagon
  4. Sisu/Plexus component wiring
  5. polyglot needs core extension

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.

solid answer

~40 s

A plugin contributes goals you bind to lifecycle phases (e.g. compiler:compile). A build extension instead augments Maven's core runtime: it can register a custom packaging type, contribute a new lifecycle mapping, add a wagon transport provider for a new repository protocol, or hook into component (Plexus/Sisu) wiring. Declared classically inside <build><extensions> in a pom, they share the project's classloader. Maven 3.3+ added <build><extensions> with isolation plus core extensions via .mvn/extensions.xml, which load even earlier — before the pom is read — so they can affect project loading itself (e.g. polyglot Maven, the Takari smart builder). So: plugins extend the build's work; extensions extend Maven's machinery.

code

xml · 8 lines
xml
<!-- .mvn/extensions.xml: loaded before the POM is read -->
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0">
  <extension>
    <groupId>io.takari.maven</groupId>
    <artifactId>takari-smart-builder</artifactId>
    <version>0.6.1</version>
  </extension>
</extensions>

go deeper

for a junior

Knows extensions add capabilities to Maven beyond ordinary plugins.

for a middle

Can name the two declaration mechanisms and that extensions affect Maven's core, not just goals.

for a senior

Understands load order, classloader/component-wiring implications, and when each mechanism is required.

for a principal

Governs extension usage across a monorepo, weighs build-machinery customization vs. maintainability and reproducibility.

## What an extension is Maven is built from small components wired together by an IoC container (historically Plexus, now Sisu/Guice). Most users customize a build with **plugins** — units that expose **goals** (like `compiler:compile`) which you bind to **lifecycle phases**. A **build extension** is different: it injects code into Maven's own runtime so it can change *how Maven behaves*, not just *what work runs*. Extensions can: - Register a new **packaging type** and its **lifecycle mapping** (which goals run in which phases). - Provide a **wagon** — a transport provider for a repository protocol Maven doesn't ship (e.g. `scp`, `webdav`, custom). - Replace or augment core components (artifact resolution, the build sequencer, etc.). - Enable **polyglot Maven** (writing the build model in YAML/Groovy/Kotlin instead of `pom.xml`). ## Two ways to declare them ### 1. Classic build extensions (`<build><extensions>`) Declared in the POM, loaded when the project is built, sharing (in older Maven) the build classloader: ```xml <build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>3.5.3</version> </extension> </extensions> </build> ``` ### 2. Core extensions (`.mvn/extensions.xml`) Since Maven 3.3.1, placed in the project's `.mvn/` directory. These load **before the POM is parsed**, so they can affect project loading itself — required for polyglot Maven and smart-builder extensions: ```xml <extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0"> <extension> <groupId>io.takari.maven</groupId> <artifactId>takari-smart-builder</artifactId> <version>0.6.1</version> </extension> </extensions> ``` ## Key contrast | | Plugin | Extension | |---|---|---| | Adds | Goals run during the build | Core capability / behavior | | Bound to | Lifecycle phases | Maven runtime wiring | | Typical use | compile, test, package, deploy | new packaging, transport, polyglot | Load order matters: core extensions (`.mvn/extensions.xml`) load earliest, then classic `<build><extensions>` when the project builds.

  • Why must polyglot Maven be a core extension rather than a build extension?
    Because the build model (the alternative to pom.xml) must be parsed before the project is loaded; only .mvn/extensions.xml loads early enough to intercept project loading.
  • Where do classic build extensions get declared?
    Inside <build><extensions><extension>...</extension></build> in the pom.xml.

Plugins are appliances you plug into the wall; extensions rewire the house's electrical panel.

saying these in an interview costs you the question

  • Saying extensions are just another name for plugins.
  • Claiming all extensions are declared in pom.xml (core extensions live in .mvn/extensions.xml).
  • Thinking extensions bind to lifecycle phases like goals do.

context

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

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

Compare core extensions (.mvn/extensions.xml) versus build extensions (<build><extensions>): when does each load, and why does it matter?

level: principalimportance: nice to knowfreq 18%

basics

~10 s

Core extensions in .mvn/extensions.xml load before the POM is read, so they can change project loading itself. Build extensions in <build><extensions> load later, while building an already-parsed project, so they're limited to build-time machinery.

open as a page