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 Descriptor.
<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.
11.3.1. Top-level Plugin Descriptor Elements
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
goalPrefix has a value of
compiler . If you look at the descriptor for the Jar plugin, it
would have a goalPrefix of jar . 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
of ClassLoader objects which are modeled by a ClassRealm
object. Feel free to ignore this property and always set it to
false .
-
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.
11.3.2. Mojo Configuration
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:compile goal, then compiler is the plugin’s
goalPrefix and compile would 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 is
false . <!--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
requiresProject is true .
-
requiresReports
-
If you were creating a plugin that relies on the presence of
reports, you would need to set
requiresReports to true . For
example, if you were writing a plugin to aggregate information from
a number of reports, you would set requiresReports to true . The
default for this element is false .
-
aggregator
-
A Mojo descriptor with
aggregator set to true is 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 with aggregator
set to true should only be run against the top-level project in a
Maven build. The default value of aggregator is false .
-
requiresOnline
-
Specifies that a given goal cannot be executed if Maven is running
in offline mode (
-o command-line option). If a goal depends on a
network resource, you would specify a value of true for this
element and Maven would print an error if the goal was executed in
offline mode. The default for requiresOnline is false .
-
inheritedByDefault
-
If
inheritedByDefault is set to true , 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 has
inheritedByDefault set to true , this execution will be
inherited by the child project. If inheritedByDefault is not set
to true , 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
ComponentFactory used 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 than java .
-
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
instantiationStrategy of per-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-session and always . 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
editable is set to false ),
then the value of the parameter cannot be set in the POM. For
example, if the plugin descriptor defines the value of
buildDirectory to 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
baseDir Mojo parameter and the
buildDirectory Mojo parameter. In the parameter element, the
implementation specifies the type of the parameter (in this case
java.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.
11.3.3. Plugin Dependencies
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.
|