Apache Maven

Create a Maven Plugin

Introduction#

Maven allows you to implement and use custom plugins. These plugins allow additional behaviour to be bound to any phase of the Maven lifecycle.

Each Maven goal is created by implementing a MOJO (Maven Ordinary Java Object): a Java class implemented with annotations that describes how to invoke it.

The goal prefix of a plugin is derived from its artifact name. An artifact hello-world-plugin creates a goal prefix hello-world. The hello goal can then be run with mvn hello-world:hello.

Remarks#

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.

Declaring a Maven artifact as a Maven 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>

Creating a goal

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");
    }
}

Using plugin configuration

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

Accessing the project information

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>

Declare a default phase for a goal

@Mojo(name = "hi", defaultPhase = LifecyclePhase.COMPILE)

Get the build directory as a file

@Parameter(defaultValue = "${project.build.directory}")
private File buildDirectory;

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow