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
This section lists all the things a developer needs to take into account in order to respect the maven plugin mechanism.
<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>
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:
Goal | Description |
---|---|
compile | Compiles the Java code for the plugin and builds the plugin descriptor |
test | Runs the plugin's unit tests |
package | Builds the plugin jar |
install | Installs the plugin jar in the local repository |
deploy | Deploys the plugin jar to the remote repository |
When processing the source tree to find plugin, plugin-tools registers classes as plugin with either:
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
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:
A plugin:
This interface defines:
The execute() method: no parameters, void return type,
public void execute() throws MojoExecutionException {
getLog().info("Hello, "+this.user+"!");
}
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:
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+"!");
}
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.
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.
With Mvn
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] ------------------------------------------------------------------------
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>
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] ------------------------------------------------------------------------
to configure the javadoc annotations as live templates, download this file, and place it in USER_HOME/.IntelliJIdea/config/templates
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.