Maven: The Complete Reference
11.3. Plugin Descriptor

A Maven plugin contains a road-map for Maven that tells Maven about the various Mojos and plugin configuration. This plugin descriptor is present in the plugin JAR file in META-INF/maven/plugin.xml. When Maven loads a plugin, it reads this XML file, instantiates and configures plugin objects to make the Mojos contained in a plugin available to Maven.
When you are writing custom Maven plugins, you will almost never need
to think about writing a plugin descriptor. In Chapter 4, The Build Lifecycle, the
lifecycle goals bound to the maven-plugin packaging type show that
the plugin:descriptor goal is bound to the generate-resources
phase. This goal generates a plugin descriptor off of the annotations
present in a plugin’s source code. Later in this chapter, you will see
how Mojos are annotated, and you will also see how the values in these
annotations end up in the META-INF/maven/plugin.xml file.
Plugin Descriptor shows a plugin descriptor for the Maven Zip Plugin. This plugin is a contrived plugin that simply zips up the output directory and produces an archive. Normally, you wouldn’t need to write a custom plugin to create an archive from Maven, you could simply use the Maven Assembly Plugin which is capable of producing a distribution archive in multiple formats. Read through the following plugin descriptor to get an idea of the content it contains.
<plugin>
<description></description>
<groupId>com.training.plugins</groupId>
<artifactId>maven-zip-plugin</artifactId>
<version>1-SNAPSHOT</version>
<goalPrefix>zip</goalPrefix>
<isolatedRealm>false</isolatedRealm>
<inheritedByDefault>true</inheritedByDefault>
<mojos>
<mojo>
<goal>zip</goal>
<description>Zips up the output directory.</description>
<requiresDirectInvocation>false</requiresDirectInvocation>
<requiresProject>true</requiresProject>
<requiresReports>false</requiresReports>
<aggregator>false</aggregator>
<requiresOnline>false</requiresOnline>
<inheritedByDefault>true</inheritedByDefault>
<phase>package</phase>
<implementation>com.training.plugins.ZipMojo</implementation>
<language>java</language>
<instantiationStrategy>per-lookup</instantiationStrategy>
<executionStrategy>once-per-session</executionStrategy>
<parameters>
<parameter>
<name>baseDirectory</name>
<type>java.io.File</type>
<required>false</required>
<editable>true</editable>
<description>Base directory of the project.</description>
</parameter>
<parameter>
<name>buildDirectory</name>
<type>java.io.File</type>
<required>false</required>
<editable>true</editable>
<description>Directory containing the build files.</description>
</parameter>
</parameters>
<configuration>
<buildDirectory implementation="java.io.File">
${project.build.directory}</buildDirectory>
<baseDirectory implementation="java.io.File">
${basedir}</baseDirectory>
</configuration>
<requirements>
<requirement>
<role>org.codehaus.plexus.archiver.Archiver</role>
<role-hint>zip</role-hint>
<field-name>zipArchiver</field-name>
</requirement>
</requirements>
</mojo>
</mojos>
<dependencies>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependencies>
</plugin>
There are three parts to a plugin descriptor: the top-level
configuration of the plugin which contains elements like groupId and
artifactId, the declaration of mojos, and the declaration of
dependencies. Let’s examine each of these sections in more detail.
The top-level configuration values in the plugin element are:
- description
- This element contains a short description of the plugin. In the case of the Zip plugin, this description is empty.
- groupId, artifactId, version
- As with everything else in Maven, plugins need to have a unique set of coordinates. The groupId, artifactId, and version are used to locate the plugin artifact in a Maven repository.
- goalPrefix
-
This element controls the prefix used to reference goals in a
particular plugin. If you were to look at the Compiler plugin’s
descriptor you would see that
goalPrefixhas a value ofcompiler. If you look at the descriptor for the Jar plugin, it would have agoalPrefixofjar. It is important that you choose a distinct goal prefix for your custom plugin. - isolatedRealm (deprecated)
-
This is a legacy property which is no longer used by Maven. It is
still present in the system to provide backwards compatibility with
older plugins. Earlier versions of Maven used to provide a
mechanism to load a plugin’s dependencies in an isolated
ClassLoader. Maven makes extensive use of a project called ClassWorlds from the Codehaus community to create hierarchies ofClassLoaderobjects which are modeled by aClassRealmobject. Feel free to ignore this property and always set it tofalse. - inheritedByDefault
- If inheritedByDefault is set to true, any mojo in this plugin which is configured in a parent project will be configured in a child project. If you configure a mojo to execute during a specific phase in a parent project and the Plugin has inheritedByDefault set to true, this execution will be inherited by the child project. If inheritedByDefault is not set to true, then an goal execution defined in a parent project will not be inherited by a child project.
Next is the declaration of each Mojo. The plugin element contains an element named mojos which contains a mojo element for each mojo present in the Plugin. Each mojo element contains the following configuration elements:
- goal
-
This is the name of the goal. If you were running the
compiler:compilegoal, thencompileris the plugin’sgoalPrefixandcompilewould be the name of the goal. - description
- This contains a short description of the goal to display to the user when they use the Help plugin to generate plugin documentation.
- requiresDirectInvocation
-
If you set this to
true, the goal can only be executed if it is explicitly executed from the command-line by the user. If someone tries to bind this goal to a lifecycle phase in a POM, Maven will print an error message. The default for this element isfalse. <!--TODO: Might want some justification.-→ - requiresProject
-
Specifies that a given goal cannot be executed outside of a
project. The goal requires a project with a POM. The default value
for
requiresProjectistrue. - requiresReports
-
If you were creating a plugin that relies on the presence of
reports, you would need to set
requiresReportstotrue. For example, if you were writing a plugin to aggregate information from a number of reports, you would setrequiresReportstotrue. The default for this element isfalse. - aggregator
-
A Mojo descriptor with
aggregatorset totrueis supposed to only run once during the execution of Maven, it was created to give plugin developers the ability to summarize the output of a series of builds; for example, to create a plugin that summarizes a report across all projects included in a build. A goal withaggregatorset totrueshould only be run against the top-level project in a Maven build. The default value ofaggregatorisfalse. - requiresOnline
-
Specifies that a given goal cannot be executed if Maven is running
in offline mode (
-ocommand-line option). If a goal depends on a network resource, you would specify a value oftruefor this element and Maven would print an error if the goal was executed in offline mode. The default forrequiresOnlineisfalse. - inheritedByDefault
-
If
inheritedByDefaultis set totrue, a mojo which is configured in a parent project will be configured in a child project. If you configure a mojo to execute during a specific phase in a parent project and the Mojo descriptor hasinheritedByDefaultset totrue, this execution will be inherited by the child project. IfinheritedByDefaultis not set totrue, then a goal execution defined in a parent project will not be inherited by a child project. - phase
- If you don’t bind this goal to a specific phase, this element defines the default phase for this mojo. If you do not specify a phase element, Maven will require the user to explicitly specify a phase in a POM.
- implementation
-
This element tells Maven which class to instantiate for this
Mojo. This is a Plexus component property (defined in Plexus
ComponentDescriptor). - language
-
The default language for a Maven Mojo is Java. This controls the
Plexus
ComponentFactoryused to create instances of this Mojo component. This chapter focuses on writing Maven plugins in Java, but you can also write Maven in a number of alternative languages such as Groovy, Beanshell, and Ruby. If you were writing a plugin in one of these languages you would use a language element value other thanjava. - instantiationStrategy
-
This property is a Plexus component configuration property, it
tells Plexus how to create and manage instances of the
component. In Maven, all mojos are going to be configured with an
instantiationStrategyofper-lookup; a new instance of the component (mojo) is created every time it is retrieved from Plexus. - executionStrategy
-
The execution strategy tells Maven when and how to execute a
Mojo. The valid values are
once-per-sessionandalways. Note: This particular property doesn’t do a thing, it is a hold over from an early design of Maven. This property is slated for deprecation in a future release of Maven. - parameters
- This element describes all of the parameters for this Mojo. What’s the name of the parameter? What is the type of parameter? Is it required? Each parameter has the following elements:
- name
-
Is the name of the parameter (i.e.
baseDirectory) - type
-
This is the type (Java class) of the parameters
(i.e.
java.io.File) - required
-
Is the parameter required? If
true, the parameter must be non-null when the goal is executed. - editable
-
If a parameter is not editable (if
editableis set tofalse), then the value of the parameter cannot be set in the POM. For example, if the plugin descriptor defines the value ofbuildDirectoryto be ${basedir} in the descriptor, a POM cannot override this value to be another value in a POM. - description
- A short description to use when generating plugin documentation (using the Help Plugin)
- configuration
-
This element provides default values for all of the Mojo’s
parameters using Maven property notation. This example provides a
default value for the
baseDirMojo parameter and thebuildDirectoryMojo parameter. In the parameter element, the implementation specifies the type of the parameter (in this casejava.io.File), the value in the parameter element contains either a hard-coded default or a Maven property reference. - requirements
- This is where the descriptor gets interesting. A Mojo is a component that is managed by Plexus, and, because of this, it has the opportunity to reference other components managed by Plexus. This element allows you to define dependencies on other components in Plexus.
While you should know how to read a Plugin Descriptor, you will almost never need to write one of these descriptor files by hand. Plugin Descriptor files are generated automatically off of a set of annotations in the source for a Mojo.
Lastly, the plugin descriptor declares a set of dependencies just like a Maven project. When Maven uses a plugin, it will download any required dependencies before it attempts to execute a goal from this plugin. In this example, the plugin depends on Jakarta Commons IO version 1.3.2.
