About
How to develop a maven plugin with Java Annotation. (It's important for the configuration).
The code result of this tutorial is on github. helloworld-maven-plugin
Requirements
This section lists all the things a developer needs to take into account in order to respect the maven plugin mechanism.
Name Convention
<pluginName>-maven-plugin
In this case
hello-maven-plugin
That you get back in the pom.xml. Example: pom.xml
<artifactId>hello-maven-plugin</artifactId>
Packaging
The packaging must be defined in the pom.xml to maven-plugin. Example: pom.xml
<packaging>maven-plugin</packaging>
There are few goals which are defined with the maven-plugin packaging as part of a standard build lifecycle:
Annotation
Mojo (Plugin Registration)
When processing the source tree to find plugin, plugin-tools registers classes as plugin with either:
- or “goal” javadoc annotation.
Any class with this annotation are included in the plugin configuration file.
Example: GreetingMojoWithParameters.java
/**
* Says "Hi" to a user given in a parameters
*/
@Mojo(name = "sayhiTo")
public class GreetingMojoWithParameters extends AbstractMojo
Parameters
From GreetingMojoWithParameters.java
/**
* The user to display.
* The parameter annotation identifies the variable as a mojo parameter.
*
*/
@Parameter( property = "sayhiTo.user", defaultValue = "World" )
private String user;
where:
- The default value can include expressions which reference the project, such as “project.version”. See PluginParameterExpressionEvaluator
- The property parameter can be used to allow configuration of the mojo parameter from the command line by referencing a system property that the user sets via the -D option.
Interface
A plugin:
- must implement the Mojo interface
- or else extend its abstract base class counterpart ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/AbstractMojo.html
This interface defines:
The Execution contract
The execute() method: no parameters, void return type,
public void execute() throws MojoExecutionException {
getLog().info("Hello, "+this.user+"!");
}
The Exception mechanism
The execute() method may throw only a MojoExecutionException and its derivatives.
public void execute() throws MojoExecutionException {
getLog().info("Hello, "+this.user+"!");
}
The execute method can throw two exceptions:
- MojoExecutionException if an unexpected problem occurs. Throwing this exception causes a “BUILD ERROR” message to be displayed.
- MojoFailureException if an expected problem (such as a compilation failure) occurs. Throwing this exception causes a “BUILD FAILURE” message to be displayed.
The (Log|Result|Feedback) mechanism
Through the function void setLog( org.apache.maven.plugin.logging.Log ), you may inject a logging mechanism
The getLog method (defined in AbstractMojo) returns a log4j-like logger object which allows plugins to create messages at levels of “debug”, “info”, “warn”, and “error”.
public void execute() throws MojoExecutionException {
getLog().info("Hello, "+this.user+"!");
}
Descriptor
Each Plugin (a packaged set of Mojos) must provide a descriptor (also known as plugin configuration file) called plugin.xml under the path META-INF/maven inside the Plugin jar file that provides metadata about the parameters and other component requirements.
See plugin.xml for its description.
This descriptor is generally generated from plugin sources, using maven-plugin-plugin in the target/classes/META-INF/maven directory.
In the pom.xml. Example: pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.4</version>
<configuration>
<goalPrefix>hello</goalPrefix>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
<phase>process-classes</phase>
</execution>
<!-- if you want to generate help goal -->
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
After calling the package phase, you will find it in the target/classes/META-INF/maven directory.
Archetype Template
You can create your project from scratch or your can use a template (an archetype).
Maven provides the maven-archetype-plugin. See maven-archetype-plugin.
The easiest way is to call the goal archetype:generate and to answer interactively the questions.
mvn archetype:generate # archetype:create is deprecated since maven 3.0.5
Then you can filter by artifactId (GroupId doesn't work for me) by entering: maven-archetype-plugin.
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : maven-archetype-plugin
Choose archetype:
1: remote -> org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.)
2: remote -> org.apache.maven.archetypes:maven-archetype-plugin-site (An archetype which contains a sample Maven plugin site. This archetype can be
existing Maven plugin project.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1
Otherwise, you can call directly the archetypeArtifactId
mvn archetype:generate # archetype:create is deprecated since maven 3.0.5
-DgroupId=sample.plugin
-DartifactId=hello-maven-plugin
-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-plugin
Unfortunately, the generated project contains a deprecated mojo and a pom.xml that doesn't find the maven-invoker-plugin.
Run your plugin
With Mvn
A goal
Without parameters
mvn sample.plugin:hello-maven-plugin:1.0-SNAPSHOT:sayhi
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Sample Parameter-less Maven Plugin 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.371 s
[INFO] Finished at: 2015-12-15T13:29:01+01:00
[INFO] Final Memory: 8M/309M
[INFO] ------------------------------------------------------------------------
With parameters
if the plugin group id is configured to sample.plugin.
mvn hello:sayhiTo -DsayhiTo.user=Nico
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Sample Parameter-less Maven Plugin 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhiTo (default-cli) @ hello-maven-plugin ---
[INFO] Hello, Nico!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.309 s
[INFO] Finished at: 2015-12-15T17:42:44+01:00
[INFO] Final Memory: 8M/309M
[INFO] ------------------------------------------------------------------------
From a pom.xml:
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>hello-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>execution1</id>
<configuration>
<user>Nico</user>
</configuration>
<goals>
<goal>sayhiTo</goal>
</goals>
</execution>
</executions>
</plugin>
Plugin Help
mvn sample.plugin:hello-maven-plugin:1.0-SNAPSHOT:help
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Sample Parameter-less Maven Plugin 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:help (default-cli) @ hello-maven-plugin ---
[INFO] Sample Parameter-less Maven Plugin 1.0-SNAPSHOT
This plugin has 3 goals:
hello:help
Display help information on hello-maven-plugin.
Call mvn hello:help -Ddetail=true -Dgoal=<goal-name> to display parameter
details.
hello:sayhi
Says 'Hi' to the user.
hello:sayhiTo
Says 'Hi' to a user given in a parameters
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.350 s
[INFO] Finished at: 2015-12-15T13:30:22+01:00
[INFO] Final Memory: 8M/309M
[INFO] ------------------------------------------------------------------------
IDE
Idea
to configure the javadoc annotations as live templates, download this file, and place it in USER_HOME/.IntelliJIdea/config/templates
Support
No mojos are created in the plugin descriptor
The mojos are found but they are not added to the descriptor. This may come from the fact that you're directory tree doesn't follow the maven standard.