Thursday, April 30, 2020

How to Create a Maven Plugin




In a recent project I've had to create a maven plugin.
The maven plugin goal was to analyze a file, and set a maven property based on the file content.
In this post, we will review the step to create such a maven plugin, and to use it.


Creating the Maven Plugin


To create the maven plugin, we create a new maven project with 2 files:

  • pom.xml - configuring the maven plugin build
  • MyPlugin.java - doing the actual plugin work

The pom.xml is pretty simple, we use maven-plugin-plugin (a very creative name...) to build a new plugin.


<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo</groupId>
    <artifactId>analyze-file</artifactId>
    <packaging>maven-plugin</packaging>



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

        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.6.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>2.2.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                </configuration>
                <executions>
                    <execution>
                        <id>mojo-descriptor</id>
                        <goals>
                            <goal>descriptor</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>


The MyPlugin.java does the actual work.
It analyzes a file, and sets a maven property based on the analysis.
Both the input file name, and the output property are configurable in the plugin run. We will later see this while presenting the usage of the plugin.
We will use the @Parameter annotation to specify a configurable parameter.


package com.dfc.maven.plugin.parsejar;


import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;

@Mojo(name = "parse")
public class MyPlugin extends AbstractMojo {

    @Component
    private MavenProject project;

    @Parameter
    private String inputFile;

    @Parameter
    private String toProperty;

    public void execute() throws MojoExecutionException {
        try {
            doWork();
        } catch (Throwable e) {
            e.printStackTrace();
            throw new MojoExecutionException("analyze " + inputFile + " failed", e);
        }
    }

    private void doWork() throws Exception {
        File file = new File(inputFile);
        getLog().info("parsing file: " + file.getAbsolutePath());

        // ... analyze the file, and set the property value
        String value = ...;

        project.getProperties().put(toProperty, value);
    }
}


Using the Maven Plugin


To use the plugin, we add it as part of another maven project's pom.xml, for example:


<build>
    <plugins>
        <plugin>
            <artifactId>analyze-file</artifactId>
            <groupId>com.demo</groupId>
            <executions>
                <execution>
                    <goals>
                        <goal>parse</goal>
                    </goals>
                    <configuration>
                        <inputFile>${basedir}/my-input-file.txt</inputFile>
                        <toProperty>analyze-output</toProperty>
                    </configuration>
                </execution>
            </executions>
        </plugin>


The configurable properties are listed as part of the configuration element of the plugin usage.


Summary


In this post we have create a configurable maven plugin, which can be reused among other maven project. By creation of our own maven plugin, we can extend the maven build to match our specialized requirements.

No comments:

Post a Comment