Create a Simple Maven Plugin
Tags: beginners, maven
Published: 2022-11-18 08:21:35

## Summary
In this post I'll demonstrate how quickly a simple Maven plugin can be created.

## Reason
Normally in Maven project you do not need to create own plugins as there likely exists a plugin which covers common scenarios. However, there are edge cases or project specific needs where having own plugin would make sense.

## What do we need

- Installed Maven (I used 3.6.3)
- Java 11+ (for lower Java version sample `POM` needs to be adjusted)
- Your favorite text editor

## Naming
Every project starts from its name. The plugin naming convention is `<yourplugin>-maven-plugin`. In sample I'll use struggzard-maven-plugin.

## Project POM
Create project directory struggzard-maven-plugin and add `pom.xml` file with content bellow:

```xml
<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.stuggzard.tutorial</groupId>
    <artifactId>struggzard-maven-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>

    <name>A Simple Maven Plugin</name>
    
    <properties>
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.0</version>
        </dependency>

        <!-- dependencies to annotations -->
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>
```
At this point maven build will likely fail as there no Mojo defined.

## Add Mojo
The "Mojo" in Maven terminology is a simple class which represents one plugin goal (e.g. print message). 

```java
package dev.struggzard.tutorial;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

/**
 * A Mojo which accepts parameter and prints it.
 */
@Mojo(name = "print")
public class MessagePrinterMojo extends AbstractMojo {

    @Parameter( property = "print.text", defaultValue = "Default text" )
    private String textParameter;

    public void execute() throws MojoExecutionException, MojoFailureException {
        getLog().info(textParameter);
    }
}
```

## Running from CLI
Maven plugin can be invoked directly from CLI using following pattern:
`mvn groupId:artifactId:version:goal`

Run plugin:
`mvn dev.stuggzard.tutorial:struggzard-maven-plugin:1.0-SNAPSHOT:print`

Output:

```
[INFO] Scanning for projects...
[INFO] 
[INFO] ---< dev.stuggzard.tutorial:struggzard-maven-plugin >---
[INFO] Building A Simple Maven Plugin 1.0-SNAPSHOT
[INFO] ---[ maven-plugin ]---
[INFO] 
[INFO] --- struggzard-maven-plugin:1.0-SNAPSHOT:print (default-cli) @ struggzard-maven-plugin ---
[INFO] Default text
[INFO] -----------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------------------
[INFO] Total time:  0.390 s
[INFO] Finished at: 2020-06-21T17:29:28+03:00
[INFO] ------------------------------------------------------------------------
```
As no parameter was passed `[INFO] Default text` was printed.

Now try passing text parameter:
`mvn dev.stuggzard.tutorial:struggzard-maven-plugin:1.0-SNAPSHOT:print -"Dprint.text=Sample Text"`

Output:

```
[INFO] Scanning for projects...
[INFO] 
[INFO] ---< dev.stuggzard.tutorial:struggzard-maven-plugin >---
[INFO] Building A Simple Maven Plugin 1.0-SNAPSHOT
[INFO] ---[ maven-plugin ]---
[INFO] 
[INFO] --- struggzard-maven-plugin:1.0-SNAPSHOT:print (default-cli) @ struggzard-maven-plugin ---
[INFO] Sample Text
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.346 s
[INFO] Finished at: 2020-06-21T17:33:08+03:00
[INFO] ------------------------------------------------------------------------
```

With passed parameter text was printed accordingly `[INFO] Sample Text`.

##Adding plugin in other Maven project
In most cases plugins are created for integration into another maven project. Here some sample Maven project `POM`:

```xml
<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.struggzard.tutorial</groupId>
    <artifactId>sample-module</artifactId>
    <version>1</version>

    <properties>
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>dev.stuggzard.tutorial</groupId>
                <artifactId>struggzard-maven-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>print</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <textParameter>Sample text</textParameter>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

By invoking `mvn clean install` on maven project Maven plugin goal `print` will be triggered with configured text parameter.

##Resources
- Plugin source code - https://github.com/struggzard/struggzard-maven-plugin
- Maven plugin guide - http://maven.apache.org/guides/plugin/guide-java-plugin-development.html