A Maven plugin is a JAR containing a maven/plugins.xml
that describes the plugin metadata. This file is generated by the maven-plugin-plugin
.
An artifact built by Maven can be declared as a Maven plugin by specifying the packaging as maven-plugin
in the pom.xml
.
<packaging>maven-plugin</packaging>
You need to declare a dependency on the plugin API and annotations.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.5</version>
<scope>provided</scope>
</dependency>
You need to add a plugin to generate the metadata.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.5</version>
</plugin>
Goals are implemented by creating a MOJO. This is a class file annotated with annotations from maven-plugin-annotations
.
@Mojo(name = "hello")
public final class HelloWorldMojo extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("Hello world");
}
}
Plugins can be configured by annotating fields with @Parameter
. The MOJO is then injected with the configuration.
@Mojo(name = "greet")
public final class GreetMojo extends AbstractMojo {
@Parameter(required = true)
public String name;
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("Hello " + name);
}
}
The name
parameter can be configured in the POM:
<plugin>
<groupId>com.mattunderscore</groupId>
<artifactId>hello-world-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<name>Matt</name>
</configuration>
</plugin>
If the greet
goal is run as a standalone goal the name
parameter can be defined as property on the command line:
mvn <plugin name>:greet -Dname=Geri
The plugin can, among others, access information about the current Maven project being built.
@Mojo(name = "project")
public final class ProjectNameMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("Hello, this is " + project.getName());
}
}
The above example would print in the console the name of the Maven project it is run on, which is specified in the <project>/<name>
element of its POM.
The MavenProject
class used in the plugin requires a dependency of maven-core
with a (default) compile
scope in the plugin's POM:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>
Furthermore, using annotations requires the following dependency in the plugin's POM:
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.5</version>
<scope>provided</scope> <!-- annotations are needed only to build the plugin -->
</dependency>
@Mojo(name = "hi", defaultPhase = LifecyclePhase.COMPILE)
@Parameter(defaultValue = "${project.build.directory}")
private File buildDirectory;