Introduction: How Maven Resolves Plugins

Introduction

Starting with 2.0, Maven allows users to execute plugins that have not yet been installed. This new feature eliminates the need to maintain local plugin installations, and provides the implicit ability to instantly take advantage of new plugin releases. However, it also means that plugin information must be resolved at build time, which can be a complex task.

This document will detail the mechanism used to resolve plugin information.

Referencing Plugins

Maven 2.0 brings with it added flexibility for referencing plugins and their mojos. Since plugin information is determined at build time, plugin prefixes can be ambiguous, and dependent on an individual user's Maven configuration. Therefore, in addition to the original mechanism of referencing a plugin by its shorthand prefix and a goal, Maven can also process plugin and mojo references that concretely specify groupId, artifactId, and optionally, version.

Most users will have little difficulty using Maven as before, referencing plugins by their prefix. However, with the introduction of the build lifecycle - and mojo bindings to that lifecycle - it is critical that lifecycle mappings be able to refer to a mojo in an unambiguous way. In fact, when dealing with lifecycle mappings, it's illegal to specify a mojo using its plugin-prefix. This helps Maven avoid the case where the 'jar' lifecycle behaves differently on two users' machines, simply due to their local Maven configurations. As a side effect of this requirement, users also have the option to specify plugins and mojos in this way from the command line.

For clarity, the following are the three ways to reference a mojo from the command line. These will all result in the clean mojo of the maven-clean-plugin being invoked:

  mvn org.apache.maven.plugins:maven-clean-plugin:2.0:clean
  mvn org.apache.maven.plugins:maven-clean-plugin:clean
  mvn clean:clean

By contrast, only the following are valid mojo references from inside a lifecycle mapping definition:

  org.apache.maven.plugins:maven-clean-plugin:2.0:clean
  org.apache.maven.plugins:maven-clean-plugin:clean

NOTE: It's probably bad form to pin a plugin reference to a specific version inside a lifecycle mapping definition, since this prevents the user from taking advantage of plugin updates.

Resolving Plugin Information

Since users have the ability to reference a plugin by its groupId and artifactId without a version, Maven must have the ability to resolve the plugin's version given these other two attributes. However, since users can also refer to a plugin by its prefix, Maven must also have the ability to resolve a plugin by this prefix alone - including resolution of the plugin's version. To handle these two scenarios, Maven employs a two-stage process for resolving plugin information.

Resolving groupId and artifactId for a Plugin

Maven's approach to resolving a plugin's groupId and artifactId given its prefix is actually relatively simple. The user can specify a set of plugin groupId's to be searched. Using repository metadata for each configured groupId, Maven will search for plugin prefix mappings using the process detailed in [1].

Resolving a Plugin's Version

When a plugin's groupId and artifactId are known, but its version is still unknown, Maven will resolve that plugin's version using a variety of sources. It will check, in order, the following:

  1. the project's POM

    This includes all plugins specified in the <build> section; this is intuitive. However, since all plugin specifications in the POM are still generally a better source of information than reverting to external sources, the <pluginManagement> section will also be searched.

    NOTE: Checking of the <pluginManagement> section is new for Maven 2.0.1.

  2. the plugin registry

    This configuration file, usually located in plugin-registry.xml within the $HOME/.m2 directory, is disabled by default. To enable it, add the following section to the settings.xml file (also within $HOME/.m2):

    <settings>
      ...
      <usePluginRegistry>true</usePluginRegistry>
      ...
    </settings>
    

    The plugin registry will maintain a mapping of groupId, artifactId for a plugin to the version to be used. It will also maintain a record of the last time the plugin was checked for updated versions; the configuration for when to check for updated versions; and a list of rejected versions of the plugin which are not to be used. If an updated version is found which has not yet been rejected, the plugin version manager will ask the user whether to use this version. The user can reject the version for now or always, or accept it for now or always. If prompting is disabled (batch mode), the plugin registry can be configured with a default answer to this question.

    See [2] for more information on the plugin registry.

    See [3] for more information on the settings.xml file.

  3. LATEST version metadata

    This is published each time a Maven plugin is deployed or installed. It is simply a pointer to the latest published version of the plugin. It differs from the SNAPSHOT metadata in that it is always present, regardless of the project's version.

    If you use the plugin registry, you can disable this check.

  4. RELEASE version metadata

    Since the LATEST metadata is always published, it obsoletes this check when #3 is enabled. However, RELEASE metadata checking is still important in order to support legacy plugin-releases, where the LATEST metadata has not been published. This check can also be useful if the LATEST metadata check has been disabled. This might be used instead of LATEST metadata if the user only wants to use supported, released plugin versions.

If all of the above resolution methods fail, the plugin cannot be located and an exception is thrown, stopping the build.