Maven Plugins & Their Configuration

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against Apache Maven 3.10.0. Every example was run on JDK 26 on 2026-10-16 in scratch projects that mimic the tidepool build (parent POM io.tidepool:tidepool-parent and its modules). Maven 3.9.16 and Maven 4.0.0-rc-7 (a release candidate) were run where the page says so. Paths in the console output were shortened and long output was filtered with grep or head, which is said each time. Plugin versions are the stable releases found on Maven Central on 2026-10-16.

Maven itself knows how to read a POM, resolve dependencies and run a lifecycle; everything else, from compiling to making a JAR, is done by plugins. A plugin is a JAR that contains one or more goals (also called Mojos), each with named parameters. A build is, in the end, a list of goal executions with configuration. This page explains how to find out what a plugin offers, how to configure it, how the configuration is merged from several places, how to keep it reproducible, and how Maven finds a plugin from the short name you type on the command line. The phases that run the goals are on Build Lifecycle, and how plugins are written is on Writing Maven Plugins.

Build plugins and reporting plugins

Maven distinguishes two kinds of plugin, by where they are configured and when they run:

  • Build plugins run while the build runs and are configured under <build><plugins>. The compiler, surefire, jar and deploy plugins are build plugins.

  • Reporting plugins run while the site is generated (mvn site) and are configured under <reporting><plugins>. The Project Info Reports and Surefire Report plugins are reporting plugins. Because their output becomes part of the web site they are supposed to be internationalised.

Some plugins are both (the catalogue below marks them B+R): Checkstyle, PMD, Javadoc and Dependency can run as a build goal that fails the build, and as a report on the site. See Site & Reporting for the reporting side.

The Ant counterparts are tasks and Antlibs (Antlibs & Namespaces); the Gradle counterpart is plugins, which add tasks and conventions (Gradle Plugins Overview). The big difference is that Maven plugins are written to a fixed contract: parameters are declared on the Mojo and documented in a generated help.

Finding out what a plugin offers: the help goal

Most Maven plugins carry a help goal that prints a description of the plugin, its goals, and, with -Ddetail, every parameter with its default and its user property. It is the first thing to run for an unfamiliar plugin, and it always describes the exact version your build uses. For the JAR plugin in tidepool-model:

mvn -B jar:help
[INFO] --- jar:3.5.1:help (default-cli) @ tidepool-model ---
[INFO] Apache Maven JAR Plugin 3.5.1
  Builds a Java Archive (JAR) file from the compiled project classes and
  resources.

This plugin has 3 goals:

jar:help
  Display help information on maven-jar-plugin.
  Call mvn jar:help -Ddetail=true -Dgoal=<goal-name> to display parameter
  details.

jar:jar
  Build a JAR from the current project.

jar:test-jar
  Build a JAR of the test classes for the current project.

(The banner and build summary lines were removed.) jar:help ran the jar plugin’s own help goal, version 3.5.1, the version the project’s pluginManagement pins. To see the parameters of one goal, add -Dgoal= and -Ddetail. The output for the compiler plugin, filtered with grep to a few parameters:

mvn -B compiler:help -Dgoal=compile -Ddetail
    compilerArgs
      Sets the arguments to be passed to the compiler.
      Note that -J options are only passed through if fork is set to true.
      Example: <compilerArgs> <arg>-Xmaxerrs</arg> <arg>1000</arg>
      <arg>-Xlint</arg> <arg>-J-Duser.language=en_us</arg> </compilerArgs>
    release
      The -release argument for the Java compiler, supported since Java9
      User property: maven.compiler.release
    showWarnings (Default: true)
      Set to false to disable warnings during compilation.
      User property: maven.compiler.showWarnings
    source (Default: 1.8)
    target (Default: 1.8)

(Whitespace trimmed; the real listing has dozens of parameters.) Each parameter has a name (what you write as an XML element in the POM), an optional default, and optionally a user property (what you can set with -D on the command line or in the POM’s <properties>). maven.compiler.release is the user property for the release parameter, which is why <maven.compiler.release>21</maven.compiler.release> in the parent POM configures the compiler. A parameter without a user property can only be set in the POM.

The Help plugin’s own describe goal is the other half: it describes a plugin from the outside, with no need for the plugin to have a help goal, and it can describe a lifecycle phase:

mvn -B help:describe -Dplugin=jar
[INFO] org.apache.maven.plugins:maven-jar-plugin:3.5.1

Name: Apache Maven JAR Plugin
Description: Builds a Java Archive (JAR) file from the compiled project
  classes and resources.
Group Id: org.apache.maven.plugins
Artifact Id: maven-jar-plugin
Version: 3.5.1
Goal Prefix: jar

This plugin has 3 goals:

jar:help
  Description: Display help information on maven-jar-plugin. Call mvn
    jar:help -Ddetail=true -Dgoal= to display parameter details.

jar:jar
  Description: Build a JAR from the current project.

jar:test-jar
  Description: Build a JAR of the test classes for the current project.

-Dplugin= accepts a prefix, groupId:artifactId or groupId:artifactId:version; -Dgoal= narrows to one goal; -Dmedium and -Ddetail add detail; -Dcmd= takes a phase or a goal (see the lifecycle page). To see what a build actually resolved, rather than what a plugin could do, use mvn help:effective-pom (see Inheritance, Aggregation & the Effective POM) or run with -X as shown below.

Configuring parameters

Configuration goes in a <configuration> element, either inside a <plugin> (applies to every execution of the plugin) or inside an <execution> (applies to that execution only). Each child element is named after a parameter. How the text is converted depends on the parameter’s Java type, which Maven’s configurator reads from the Mojo. The following scratch module, tidepool-conf-demo, configures a simple value, a list, a complex object, a map and a properties block in one build:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <release>21</release>
        <showWarnings>true</showWarnings>
        <compilerArgs>
          <arg>-Xlint:all</arg>
          <arg>-parameters</arg>
        </compilerArgs>
        <annotationProcessorPaths>
          <path>
            <groupId>info.picocli</groupId>
            <artifactId>picocli-codegen</artifactId>
            <version>4.7.7</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <systemPropertyVariables>
          <tidepool.station>harbour</tidepool.station>
          <tidepool.level>1</tidepool.level>
        </systemPropertyVariables>
        <properties>
          <configurationParameters>
            junit.jupiter.execution.parallel.enabled = true
            junit.jupiter.execution.parallel.mode.default = concurrent
          </configurationParameters>
        </properties>
        <excludes>
          <exclude>**/Slow*.java</exclude>
        </excludes>
      </configuration>
    </plugin>
  </plugins>
</build>

The versions of the two plugins come from the parent’s pluginManagement (below). mvn -B -X test prints, for each execution, the value Maven injected into each parameter. Filtered to the interesting lines:

[DEBUG] Configuring mojo execution 'org.apache.maven.plugins:maven-compiler-plugin:3.16.0:compile:default-compile' with basic configurator -->
[DEBUG]   (s) groupId = info.picocli
[DEBUG]   (s) artifactId = picocli-codegen
[DEBUG]   (s) version = 4.7.7
[DEBUG]   (f) annotationProcessorPaths = [info.picocli:picocli-codegen:4.7.7.jar]
[DEBUG]   (f) compilerArgs = [-Xlint:all, -parameters]
[DEBUG]   (s) release = 21
[DEBUG]   (f) showWarnings = true
[DEBUG] Configuring mojo execution 'org.apache.maven.plugins:maven-surefire-plugin:3.6.0:test:default-test' with basic configurator -->
[DEBUG]   (s) excludes = [**/Slow*.java]
[DEBUG]   (s) properties = {configurationParameters=junit.jupiter.execution.parallel.enabled = true
              junit.jupiter.execution.parallel.mode.default = concurrent}
[DEBUG]   (s) systemPropertyVariables = {tidepool.level=1, tidepool.station=harbour}

The test in the module reads the two system properties and passes, so the map really reached the forked test JVM. (s) and (f) say how the value was injected (through a setter or straight into a field); they describe how the plugin author declared the parameter, not where the value came from.

The mapping rules, with the examples above:

Parameter type POM form Example above

Simple values (String, boolean, int, File, URL, enum, …​)

The element text, converted by the Maven configurator; a path is relative to the project base directory for a File.

<release>21</release>, <showWarnings>true</showWarnings>

Complex objects (a class or interface)

Child elements are matched to the object’s fields or setters by name; the type can be given with an implementation attribute when the declared type is an interface.

<path> with groupId, artifactId and version

Lists and arrays

Repeat a child element; the name is the (singular) element name chosen by the plugin author, often derived from the parameter name. compilerArgs takes <arg>, excludes takes <exclude>.

<compilerArgs><arg>... and <excludes><exclude>...

Maps

Each child element is a key, its text the value.

<systemPropertyVariables> with tidepool.station and tidepool.level

java.util.Properties

Repeated <property> elements with <name> and <value> children (the surefire properties parameter instead takes <configurationParameters> text, as shown, because it forwards raw provider settings).

<properties><configurationParameters>

POM configuration versus the command line

A parameter that has a user property can be set from the command line, but an explicit <configuration> value in the POM beats the user property. In tidepool-conf-demo, where the compiler’s <release>21</release> is written in the POM, mvn -B -X -Dmaven.compiler.release=17 compile still prints (s) release = 21. In a project where the value arrives only through the maven.compiler.release POM property, the same -D wins:

$ mvn -B -X -Dmaven.compiler.release=17 compile   # release only via the POM property (21)
[DEBUG]   (s) release = 17
$ mvn -B -X compile
[DEBUG]   (s) release = 21

The idiom that follows is: put a default in a POM property (<maven.compiler.release>21</maven.compiler.release>) and let callers override it with -D; write the value as plugin configuration only when it must not be overridable. The Ant equivalent is the same rule in other words: a property is overridable by -D and a hard-coded attribute is not. See Ant Properties.

Executions: id, phase and goals

An <execution> binds goals to a phase, with its own configuration. It has:

  • <id>, unique among the executions of that plugin in one POM. Ids are not unique across a parent and a child POM: an execution with the same id in the child replaces the parent’s, and executions with different ids are all kept and run parent first. The id appears in the build log in parentheses, and default-<goal> and default-cli are reserved for the implied executions (see the lifecycle page).

  • <phase>, the phase to bind to. It can be omitted when the goal declares a default phase (for example jar:test-jar runs in package); with no phase and no default, the execution is never run by the lifecycle. <phase>none</phase> unbinds an execution.

  • <goals>, one or more <goal> elements. Two goals of one execution run in the same phase, in the order written, and share the execution’s configuration.

  • <configuration> for the execution, merged over the plugin-level configuration.

  • <inherited>false</inherited> to keep the execution out of child POMs.

Multiple executions in one phase run in declaration order, parents first. Maven 4 (release candidate) adds explicit ordering with phase[200], which Maven 3 ignores silently; the lifecycle page has a run of both.

The guide’s example (two executions of one plugin, different configuration, different phases) is the standard way to run a goal more than once with different settings:

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-stations</id>
      <phase>generate-resources</phase>
      <goals><goal>copy-resources</goal></goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}/data</outputDirectory>
        <resources>
          <resource><directory>${project.basedir}/../data</directory></resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

This is the execution run in the lifecycle page (resources:3.5.0:copy-resources (copy-stations) in generate-resources).

Plugin dependencies

A plugin runs in its own class realm, with its own dependencies, apart from the project’s. Some plugins load extra classes at run time that you must supply: a different compiler for the compiler plugin, a different test provider for surefire, a JDBC driver for a SQL plugin, Ant tasks for the AntRun plugin. You add them with <dependencies> inside the <plugin>:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.16.0</version>
  <configuration>
    <compilerId>eclipse</compilerId>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-compiler-eclipse</artifactId>
      <version>2.17.0</version>
    </dependency>
  </dependencies>
</plugin>

With the dependency, a one-class module compiles with the Eclipse compiler:

[INFO] --- compiler:3.16.0:compile (default-compile) @ tidepool-plugin-deps-demo ---
[INFO] Compiling with eclipse [debug release 21] to target/classes
[INFO] BUILD SUCCESS

Without the <dependencies> block (same compilerId), the build fails with:

[ERROR] Compiler 'eclipse' could not be instantiated or injected properly. If you spelled the compiler ID correctly and all necessary dependencies are on the classpath, then next you can try running the build with -Dsisu.debug, looking for exceptions. ...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.16.0:compile (default-compile) on project tidepool-plugin-deps-demo: No such compiler 'eclipse'. -> [Help 1]

(The long first line was cut after the first sentence.) The plugin dependency’s version has to match what the plugin was built against. With plexus-compiler-eclipse:2.17.1 the same project failed against compiler plugin 3.16.0, which uses Plexus Compiler 2.17.0:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.16.0:compile (default-compile) on project tidepool-plugin-deps-demo: Execution default-compile of goal org.apache.maven.plugins:maven-compiler-plugin:3.16.0:compile failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-compiler-plugin:3.16.0:compile: java.lang.NoSuchMethodError: 'java.lang.String org.codehaus.plexus.compiler.eclipse.EclipseJavaCompiler.joinAnnotationProcessors(java.lang.String[])'

Look at the plugin’s POM (maven-compiler-plugin-3.16.0.pom defines plexusCompilerVersion as 2.17.0) when choosing such a version. Plugin dependencies are not project dependencies: they do not appear on the project’s classpath, and they are not inherited into the dependency graph of the artifact. The Ant counterpart of a plugin dependency is a library placed on the taskdef classpath; the Gradle counterpart is the buildscript classpath or pluginManagement.

Inheritance of plugin configuration

A child POM inherits the <build><plugins> of its parent, with the configuration and executions. To keep a plugin out of the children, set <inherited>false</inherited> on the plugin (or on a single execution). A parent that declares the Help plugin’s system goal in validate, once with the default and once with inherited false, in a two-module reactor (only the --- plugin --- lines shown):

### default (inherited)
[INFO] Building inh-parent 1.0.0-SNAPSHOT                                 [1/2]
[INFO] --- help:3.5.2:system (say-where) @ inh-parent ---
[INFO] Building inh-child 1.0.0-SNAPSHOT                                  [2/2]
[INFO] --- help:3.5.2:system (say-where) @ inh-child ---
### <inherited>false</inherited>
[INFO] Building inh-parent 1.0.0-SNAPSHOT                                 [1/2]
[INFO] --- help:3.5.2:system (say-where) @ inh-parent ---
[INFO] Building inh-child 1.0.0-SNAPSHOT                                  [2/2]

<inherited> is a literal: an attempt to give it a property reference (${some.flag}) did not behave as a switch in the run (the goal ran only in the parent), so write true or false.

Merging configuration: combine.children and combine.self

When a parent and a child both configure the same plugin, Maven merges the two <configuration> trees element by element: scalar elements are overridden by the child, elements only one side has are kept, and a list element is merged by element name. The surprising consequence is that a child list replaces the parent’s list. With the parent’s pluginManagement giving the compiler <showWarnings>true</showWarnings> and compilerArgs of -Xlint:all, and the child adding <showDeprecation>true</showDeprecation> and a compilerArgs of -parameters, mvn -B -X -pl child compile printed:

### child compilerArgs without an attribute
[DEBUG]   (f) compilerArgs = [-parameters]
[DEBUG]   (f) showDeprecation = true
[DEBUG]   (f) showWarnings = true
### child <compilerArgs combine.children="append">
[DEBUG]   (f) compilerArgs = [-Xlint:all, -parameters]
### child <compilerArgs combine.self="override">
[DEBUG]   (f) compilerArgs = [-parameters]

-Xlint:all was lost without an attribute. combine.children="append" appends the child’s elements to the parent’s, so both arguments reach javac; combine.self="override" makes the child’s element replace the parent’s completely (which is also what happens by default for this list, but it documents the intent and also removes parent keys inside complex objects). Both attributes are written on the element that is being merged. Note that all three runs kept showWarnings = true from the parent and showDeprecation = true from the child: scalar siblings merge freely.

Plugin management

<build><pluginManagement> declares versions, configuration and executions for plugins without activating them: they take effect only for a plugin that is actually used, by the lifecycle (packaging bindings) or by a <plugin> entry in a <plugins> section. It is the plugin counterpart of dependencyManagement, and the place for plugin versions and shared configuration in a parent POM. The tidepool parent:

<build>
  <pluginManagement>
    <plugins>
      <plugin><artifactId>maven-clean-plugin</artifactId><version>3.5.0</version></plugin>
      <plugin><artifactId>maven-resources-plugin</artifactId><version>3.5.0</version></plugin>
      <plugin><artifactId>maven-compiler-plugin</artifactId><version>3.16.0</version></plugin>
      <plugin><artifactId>maven-surefire-plugin</artifactId><version>3.6.0</version></plugin>
      <plugin><artifactId>maven-failsafe-plugin</artifactId><version>3.6.0</version></plugin>
      <plugin><artifactId>maven-jar-plugin</artifactId><version>3.5.1</version></plugin>
      <plugin><artifactId>maven-install-plugin</artifactId><version>3.2.0</version></plugin>
      <plugin><artifactId>maven-deploy-plugin</artifactId><version>3.2.0</version></plugin>
      <plugin><artifactId>maven-site-plugin</artifactId><version>3.22.0</version></plugin>
    </plugins>
  </pluginManagement>
</build>

(groupId is omitted: it defaults to org.apache.maven.plugins.) maven-failsafe-plugin is managed here but is not used by tidepool-model, and the verify build of that module shows no failsafe line: management does not bind anything. The child modules do not repeat the versions, and every --- compiler:3.16.0:compile --- line in the logs on this page comes from this block. On Maven 3.10.0 the super POM no longer contains a pluginManagement section (it was removed in 3.10, together with the release-profile profile); on 3.9.x it managed only four plugins, maven-antrun-plugin, maven-assembly-plugin, maven-dependency-plugin and maven-release-plugin. The versions of the plugins bound by the packaging (clean, resources, compiler, surefire, jar, install and deploy, among others) never came from the super POM: they come from the lifecycle bindings of the running Maven, which still supply them on 3.10.0 but change from one Maven release to the next, so every project that wants stable versions must pin its own.

Pinning every plugin version

A plugin entry without a <version> is accepted, with a warning, and Maven decides the version: for a plugin bound by the packaging, the default that the running Maven carries; for another plugin, the latest release found in the repositories. Both change when Maven or the repository changes, so a build that worked last year can differ today. A minimal POM with a maven-jar-plugin declared without a version, run on the two Mavens:

### Maven 3.10.0
[WARNING] Some problems were encountered while building the effective model for io.tidepool:tidepool-warn-demo:jar:1.0.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-jar-plugin is missing. @ line 14, column 15
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[INFO] --- jar:3.5.1:jar (default-jar) @ tidepool-warn-demo ---
### Maven 3.9.16
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-jar-plugin is missing. @ line 14, column 15
[INFO] --- jar:3.5.0:jar (default-jar) @ tidepool-warn-demo ---

(The blank [WARNING] lines were removed.) The same POM produced jars from two different plugin versions. Plugins also check the Maven version: a plugin line written for Maven 4 refuses to run on Maven 3. With maven-compiler-plugin 4.0.0-beta-5 (the Maven 4 line of the compiler plugin, a pre-release):

### Maven 3.10.0
[ERROR] The plugin org.apache.maven.plugins:maven-compiler-plugin:4.0.0-beta-5 has unmet prerequisites:
[ERROR] 	Required Maven version 4.0.0-rc-6 is not met by current version 3.10.0
### Maven 4.0.0-rc-7
[INFO] --- compiler:4.0.0-beta-5:compile (default-compile) @ tidepool-ids-demo ---
[INFO] BUILD SUCCESS

So the rule for this site is: pin every plugin in pluginManagement of the parent, stay on the 3.x lines of the plugins for Maven 3 (compiler 3.16.0, surefire 3.6.0, jar 3.5.1, and so on), and move to the 4.x lines only together with Maven 4.

A duplicate plugin entry is the other thing to clean up. A POM that declares maven-compiler-plugin twice in <plugins>:

### Maven 3.9.16 (warning, the build continued and finished with BUILD SUCCESS)
[WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-compiler-plugin @ line 21, column 15
### Maven 3.10.0 (error)
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-compiler-plugin @ line 21, column 15
[ERROR] The build could not read 1 project -> [Help 1]
### Maven 4.0.0-rc-7 (error)
[ERROR] Encountered 1 problem(s) while processing the POMs
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]     'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-compiler-plugin @ io.tidepool:tidepool-warn-demo:1.0.0-SNAPSHOT, file:///...

This is one of the "stricter POM validation" changes of 3.10 (the escape hatch the release notes name is -Dmaven.resolver.validation=off; on 3.10.0 the lower-case value fails with No enum constant, and the property governs coordinate validation rather than this check, see Maven Dependencies, Scopes & Mediation). Use two <execution> elements instead of two <plugin> entries. The help plugin’s help:effective-pom shows the version Maven resolved for every plugin.

Plugin prefixes and pluginGroups

You type mvn jar:help, not mvn org.apache.maven.plugins:maven-jar-plugin:3.5.1:help. The short name, jar, is the plugin’s goal prefix. Maven turns a prefix into a groupId:artifactId as follows:

  1. The plugins already known to the project (declared in <build><plugins> or pluginManagement, or implied by the packaging) are searched first. If one of them has that prefix, it is used.

  2. Otherwise Maven reads the repository metadata file maven-metadata.xml of every group in the plugin groups list, from the local and the remote repositories. Each such file maps prefixes to artifact ids. The default list is org.apache.maven.plugins and org.codehaus.mojo, and <pluginGroups> in settings.xml adds more.

  3. If nothing matches, the build fails.

The metadata for a group is a plain XML file. This is the whole content for org.jacoco:

<metadata>
  <plugins>
    <plugin>
      <name>JaCoCo :: Maven Plugin</name>
      <prefix>jacoco</prefix>
      <artifactId>jacoco-maven-plugin</artifactId>
    </plugin>
  </plugins>
</metadata>

(From https://repo.maven.apache.org/maven2/org/jacoco/maven-metadata.xml; the org/apache/maven/plugins file lists 65 plugin entries at the time of writing.) Maven 3.10.0 also logs Loaded 24109 auto-discovered prefixes for remote repository central (prefixes-central.txt) at the start of each build; that is the repository’s published prefix list and is part of the remote repository filtering introduced in the 3.9 line, not a prefix mapping.

Running mvn jacoco:help in tidepool-model on Maven 3.10.0 first fails, because org.jacoco is not a default group (Maven 3.9.16 printed the same error). The two downloads are the two default groups:

[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
[ERROR] No plugin found for prefix 'jacoco' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/albertoirurueta/.m2/repository), central (https://repo.maven.apache.org/maven2)] -> [Help 1]

The error message names the three places that were searched, which is exactly the lookup order above. There are three ways to fix it. The first is a settings.xml with the group added; run here with -s settings-groups.xml:

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
  <pluginGroups>
    <pluginGroup>org.jacoco</pluginGroup>
  </pluginGroups>
</settings>
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/jacoco/maven-metadata.xml
[INFO] --- jacoco:0.8.15:help (default-cli) @ tidepool-model ---
[INFO] JaCoCo :: Maven Plugin 0.8.15
This plugin has 11 goals:

(Filtered.) The second is to declare the plugin in the POM (a project plugin is searched first), with a version, which also gives the plugin the pinned version it should have; with jacoco-maven-plugin 0.8.15 declared in a scratch POM, mvn jacoco:help printed --- jacoco:0.8.15:help (default-cli) --- with no pluginGroups at all. The third is to spell out the coordinates: mvn org.jacoco:jacoco-maven-plugin:0.8.15:help.

The org.codehaus.mojo group is the default because of the MojoHaus plugins that moved out of Codehaus: mvn versions:help resolved versions-maven-plugin 2.23.0 from org.codehaus.mojo with no configuration, and, being unpinned, resolved to the latest release. Two further forms are accepted on the command line, both run here:

mvn -B compiler:3.16.0:help
mvn -B org.apache.maven.plugins:maven-compiler-plugin:3.16.0:help

Both printed --- compiler:3.16.0:help (default-cli) ---. The prefix:version:goal form (version in the middle) is available since Maven 3.9.0 and is the way to run a goal at a specific version without a POM entry.

The prefix is chosen by the plugin author, conventionally the artifact id without the maven- and -plugin affixes (maven-jar-plugin is jar). Maven plugins named maven-*-plugin are reserved for the Apache Maven project; a third-party plugin is named <name>-maven-plugin so that its prefix is <name>, as with jacoco-maven-plugin and versions-maven-plugin.

Plugin validation warnings

Since Maven 3.9.0 and in Maven 4, Maven checks the plugins a build uses and reports configuration it knows is wrong or risky. The guide splits the problems into internal ones, which you fix in your POM (a deprecated parameter, a read-only parameter set in configuration, a deprecated goal), and external ones, which are defects of the plugin itself (it uses a deprecated Maven API, or declares Maven core artifacts in the wrong scope) and are fixed by upgrading or reporting them to the plugin authors.

A scratch POM, tidepool-validation-demo, makes three mistakes: it configures <sourceLevel> (a parameter the compiler plugin does not have), <systemProperties> (a deprecated surefire parameter) and <finalName> (a read-only parameter of the jar plugin). mvn -B package on 3.10.0:

[WARNING] Parameter 'sourceLevel' is unknown for plugin 'maven-compiler-plugin:3.16.0:compile (default-compile)'
[WARNING] Parameter 'sourceLevel' is unknown for plugin 'maven-compiler-plugin:3.16.0:testCompile (default-testCompile)'
[WARNING]  Parameter 'systemProperties' is deprecated: use systemPropertyVariables instead
[WARNING]  Parameter 'finalName' is read-only, must not be used in configuration
[INFO] Building jar: /work/lifecycle/demo-val/target/renamed.jar
[INFO] BUILD SUCCESS

The build succeeded, and the jar plugin even used the "read-only" name (renamed.jar). Validation does not stop the build; it warns that the next plugin release may. The behaviour is controlled by the user property maven.plugin.validation, whose values are case-insensitive NONE, INLINE (the default), BRIEF, SUMMARY and VERBOSE. It can be set on the command line, in MAVEN_OPTS or MAVEN_ARGS, in .mvn/maven.config, or as a settings.xml property, but not as a POM property. The same build with each value:

Value What was printed on 3.10.0 (same scratch project)

default / INLINE

The three internal issues in place, as above.

NONE

Only the two Parameter 'sourceLevel' is unknown warnings. The "unknown parameter" check is not controlled by this property.

BRIEF

The same as INLINE here: internal issues in place; external issues would be listed at the end (this project had none).

SUMMARY

The unknown-parameter lines, then a list at the end of the build: Plugin [INTERNAL, EXTERNAL] validation issues were detected in following plugin(s) followed by org.apache.maven.plugins:maven-jar-plugin:3.5.1 and org.apache.maven.plugins:maven-surefire-plugin:3.6.0.

VERBOSE

The same list with the pom.xml line where each plugin is declared and the issue text under it (below).

mvn -B -Dmaven.plugin.validation=verbose package
[WARNING] Plugin [INTERNAL, EXTERNAL] validation issues were detected in following plugin(s)
[WARNING]  * org.apache.maven.plugins:maven-jar-plugin:3.5.1
[WARNING]   Declared at location(s):
[WARNING]    * io.tidepool:tidepool-validation-demo:1.0.0-SNAPSHOT (pom.xml) @ line 29
[WARNING]   Mojo INTERNAL issue(s):
[WARNING]    * Mojo jar:jar (org.apache.maven.plugins.jar.JarMojo)
[WARNING]      - Parameter 'finalName' is read-only, must not be used in configuration
[WARNING]  * org.apache.maven.plugins:maven-surefire-plugin:3.6.0
[WARNING]   Declared at location(s):
[WARNING]    * io.tidepool:tidepool-validation-demo:1.0.0-SNAPSHOT (pom.xml) @ line 21
[WARNING]   Mojo INTERNAL issue(s):
[WARNING]    * Mojo surefire:test (org.apache.maven.plugin.surefire.SurefireMojo)
[WARNING]      - Parameter 'systemProperties' is deprecated: use systemPropertyVariables instead
[WARNING] Fix reported issues by adjusting plugin configuration or by upgrading above listed plugins. If no upgrade available, please notify plugin maintainers about reported issues.
[WARNING] For more or less details, use 'maven.plugin.validation' property with one of the values (case insensitive): [NONE, INLINE, SUMMARY, BRIEF, VERBOSE]

(Blank [WARNING] lines removed.) A plugin that you cannot fix can be excluded with -Dmaven.plugin.validation.excludes=<groupId>:<artifactId>:<version>[,...]. With the jar plugin excluded, the finalName warning disappeared and the other two kinds remained:

[WARNING] Parameter 'sourceLevel' is unknown for plugin 'maven-compiler-plugin:3.16.0:compile (default-compile)'
[WARNING] Parameter 'sourceLevel' is unknown for plugin 'maven-compiler-plugin:3.16.0:testCompile (default-testCompile)'
[WARNING]  Parameter 'systemProperties' is deprecated: use systemPropertyVariables instead

Maven 3.9.16 and 4.0.0-rc-7 printed the same four warnings for this project with the default setting. The old guide URL guide-plugin-validation.html under the mini guides is a 404; the page lives at guides/plugins/validation/.

Reporting plugins in the POM

Reporting plugins are configured in <reporting><plugins>, optionally with <reportSets> to choose which of the plugin’s reports to generate and <inherited> as for build plugins. A scratch project with the Site plugin pinned in <build> and the Project Info Reports plugin in <reporting>:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-site-plugin</artifactId>
      <version>3.22.0</version>
    </plugin>
  </plugins>
</build>
<reporting>
  <plugins>
    <plugin>
      <artifactId>maven-project-info-reports-plugin</artifactId>
      <version>3.9.0</version>
      <reportSets>
        <reportSet>
          <reports>
            <report>summary</report>
            <report>dependencies</report>
          </reports>
        </reportSet>
      </reportSets>
    </plugin>
  </reporting>
</reporting>

mvn -B site produced target/site/summary.html and project-info.html and logged Configured 2 reports for maven-project-info-reports-plugin:3.9.0: summary, dependencies (the dependency report was skipped because the project had no dependencies). Configuration in <reporting> and in <build> do not have the same effect: since the Site plugin 3.4, mvn site uses the <configuration> of a plugin in <reporting> and, additionally, that of the same plugin in <build>; but a report goal invoked directly (mvn project-info-reports:summary) ignores <reporting> and uses only <build>.

The plugin catalogue

The Maven project’s plugin index lists the plugins it maintains, with their latest versions. The table gives the stable versions found on Maven Central on 2026-10-16 (the Maven 3 lines), by group, with their typical use. B means build plugin, R reporting plugin.

Plugin (prefix) Version Type Purpose

Core plugins (bound to the default phases)

clean

3.5.0

B

Clean up after the build.

compiler

3.16.0

B

Compile Java sources.

resources

3.5.0

B

Copy resources to the output directory.

surefire

3.6.0

B

Run unit tests.

failsafe

3.6.0

B

Run integration tests and verify them in a later phase.

jar

3.5.1

B

Build a JAR.

install

3.2.0

B

Install the artifact into the local repository.

deploy

3.2.0

B

Deploy the artifact to a remote repository.

site

3.22.0

B

Generate the project site.

Packaging types and tools

war, ear, ejb, rar, app-client (acr)

3.5.1, 3.4.0, 3.3.0, 3.1.0, 3.2.0

B

Build the respective archive.

shade

3.6.2

B

Build an uber JAR with relocation.

source

3.4.0

B

Build a sources JAR.

jlink, jmod

3.3.0, 3.0.0

B

Build a Java runtime image or JMOD files.

Reporting plugins

project-info-reports

3.9.0

R

Standard project reports.

surefire-report

3.6.0

R

Unit test report.

javadoc

3.12.0

B+R

Generate Javadoc.

checkstyle, pmd

3.6.0, 3.28.0

B+R

Style and static-analysis reports and checks.

jxr, changelog, changes, plugin-report

3.6.0, 3.0.0-M2, 3.0.0-M3, 3.16.0

R, R, B+R, R

Source cross-reference, SCM changelog, change report, plugin documentation.

Tools

help

3.5.2

B

Information about the project and plugins (help:describe, help:effective-pom).

dependency

3.11.0

B+R

Analyse, copy and unpack dependencies.

enforcer

3.6.3

B

Fail the build on environment or dependency rule violations.

assembly

3.8.0

B

Build distributions of sources and binaries.

antrun

3.2.0

B

Run Ant tasks from a phase.

archetype

3.4.1

B

Generate projects from archetypes.

gpg

3.2.8

B

Sign artifacts.

release

3.3.1

B

Release workflow (version, tag).

toolchains

3.3.0

B

Select a JDK for plugins.

wrapper

3.3.4

B

Install the Maven Wrapper.

plugin (plugin:descriptor)

3.16.0

B

Generate plugin descriptors for the maven-plugin packaging.

invoker

3.10.1

B+R

Run Maven projects and verify the output (plugin integration tests).

artifact

3.7.0

B

Tasks around reproducible builds of artifacts.

The index also lists the Maven 4 lines, which run only on Maven 4: maven-compiler-plugin 4.0.0-beta-5, maven-clean-plugin and maven-install-plugin and maven-deploy-plugin 4.0.0-beta-3, maven-resources-plugin 4.0.0-beta-2, all pre-releases at the time of writing; the run above shows the compiler plugin’s prerequisite check.

Retired plugins

The index has a "Retired" table of plugins that are no longer maintained. Do not add them to new builds:

Plugin Retired Note

eclipse, idea

2015, 2013

IDE project generators; IDEs import the POM directly now.

ant

2019

Generated an Ant build file.

reactor

2014

A Maven 2 reactor helper, replaced by -pl/-am.

one, repository

2013, 2019

Maven 1 and repository helpers.

docck, patch

2023, 2024

Documentation checker; applying patches (use the Antrun plugin or a dedicated tool).

pdf

2025

PDF site output.

linkcheck

2025

Link checking.

stage, verifier

2025

Release staging and conditions verification (2025-11-29).

Plugins outside the Maven project

The index also points at the MojoHaus project (formerly Codehaus), whose plugins are third party and use the org.codehaus.mojo group (a default plugin group): versions 2.23.0, build-helper 3.6.2, flatten 1.8.0 and exec 3.6.4 are the ones used in this section, and buildplan, animal-sniffer, sql and others exist. Other products ship their own plugins: JaCoCo (org.jacoco), OWASP Dependency-Check, CycloneDX, Cargo and the Jetty and Tomcat plugins are listed on the same page. Third-party plugins need a <version> pinned like any other, and, as jacoco:help showed, their group in pluginGroups or an explicit <plugin> entry before the short prefix works.

Equivalents in Ant and Gradle

Maven Ant Gradle

A plugin and its goals

A task or an Antlib (<javac>, an antlib namespace).

A plugin (java, application) that registers tasks such as compileJava.

Goal parameters, <configuration>

Task attributes and nested elements.

Task properties and the plugin’s extension (java { ... }, tasks.compileJava { ... }).

Plugin dependencies

The classpath of taskdef or the Antlib.

The buildscript classpath, or plugins { id(...) version "..." }.

pluginManagement and pinned versions

Version numbers in get/Ivy files; no central mechanism.

pluginManagement { plugins { ... } } in settings.gradle.kts.

mvn help:describe, mvn jar:help

ant -projecthelp for targets; ant -diagnostics.

gradle help --task <name>, gradle tasks --all.