1

Preface

In the daily development of maven projects, there are relatively few opportunities for us to develop maven plug-ins by ourselves, because the maven plug-ins on the market can basically meet our daily development needs. Maven official also provides a lot of plug-ins, details can be seen in the following link

https://maven.apache.org/plugins/index.html

Today is mainly to introduce the process steps of developing a maven plug-in

maven plugin development

There are two kinds of maven plug-in development, one is based on java doc development, the other is based on annotation development

java doc development

This can directly use the skeleton that comes with maven

image.png
Select maven-archetype-mojo to generate the template, the generated template is as follows

/**
 * Goal which touches a timestamp file.
 *
 * @goal touch
 * 
 * @phase process-sources
 */
public class MyMojo
    extends AbstractMojo
{
    /**
     * Location of the file.
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private File outputDirectory;

    public void execute()
        throws MojoExecutionException
    {
        File f = outputDirectory;

        if ( !f.exists() )
        {
            f.mkdirs();
        }

        File touch = new File( f, "touch.txt" );

        FileWriter w = null;
        try
        {
            w = new FileWriter( touch );

            w.write( "touch.txt" );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error creating file " + touch, e );
        }
        finally
        {
            if ( w != null )
            {
                try
                {
                    w.close();
                }
                catch ( IOException e )
                {
                    // ignore
                }
            }
        }
    }
}

This kind of stupid generation according to the skeleton, if you are interested, you can try it, and I won't discuss it here.

Appendix: Maven document development common doc explanation

Each mojo must use the @Goal annotation to indicate its goal name, otherwise maven will not be able to recognize the goal. There are many other annotations, listed as follows:

@goal <name>: The only annotation that must be declared. When the user invokes the command line or configures the plug-in in the pom, you need to use the target name. If you are running the compiler:compile target, the compiler is the goalPrefix of the plug-in, and the compile is the target. name

@phase <phase>: By default, the goal is bound to a certain phase of the default lifecycle, so that when configuring and using the plug-in goal, there is no need to declare the phase. For example, the test goal of maven-surefire-plugin is marked with @phase tes

@requiresDependencyResolution <scope>: Before running mojo, all dependencies of the specified scope must be resolved. For example, the test target of maven-surefire-plugin is marked with requirementsDependencyResolution test, which means that all dependencies of the test scope must be resolved before the test is executed.

@requiresProject <true/false>: Whether the goal must be run in a maven project (for example, the test plug-in is used to test other projects), the default is true. Most plug-in goals need to rely on a project to run, but the system goal of maven-help-plugin is an exception, it is used to display system properties and environment variable information, without the actual project.

@requiresOnline <true/false>: Whether maven must be online, the default value is false

@requiresReport <true/false>: Whether the project report is required to have been generated, the default is false

@aggregator: When mojo runs on a multi-module project, this annotation indicates that the target will only run on the top-level module.

@requiresDirectInvocation <true/false>: When true, the target can only be directly invoked through the command line. The default is false

@execute goal="<goal>": Before running this goal, let maven run another goal. If it is the target of this plugin, call the target name directly, otherwise, use "prefix:goal"

@execute phase="<phase>": Before running the goal, let maven run a parallel life cycle until the specified phase. The plug-in target is not executed until the phase is executed

@execute lifecycle="<lifecycle>" phase = "<phase>": Before running the goal, let maven run a custom lifecycle until the specified phase.

parameters: This element describes all the parameters of Mojo. name, type, required, editable (whether it is allowed to be set in pom.xml), description, if you can use @parameter to mark a field of mojo as a configurable parameter, that is, a mojo parameter. Support boolean, int, float, String, Date, File, Url array, Collection, map, Properties

configuration: Provide default values for all Mojo parameters

Note : This explanation is taken from the blog of the blogger Bobo 86
https://blog.csdn.net/bobozai86/article/details/106179288

Annotation development

1. Introduce pom.xml
<dependencies>
      <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>3.5.2</version>
        <scope>provided</scope>
      </dependency>

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

  </dependencies>

Note: pom needs to be specified as maven-plugin

2. Write the plug-in class to inherit org.apache.maven.plugin.AbstractMojo
@Mojo(name = "echo",defaultPhase = LifecyclePhase.PACKAGE)
public class EchoMojo extends AbstractMojo {


    @Parameter
    private String applicationName;

    public void execute() throws MojoExecutionException, MojoFailureException {

        getLog().info("echo-->" + applicationName);
    }
}

@Mojo tells maven that this is not an ordinary java class, but a mojo plug-in class, defaultPhase is to specify which phase of the maven life cycle triggers execution by default

The plug-in can trigger execution in the following stages
image.png
@Parameter This function has two functions

  • It provides hooks to allow the user to adjust the operation of the plugin to suit their needs.
  • It provides a means to easily extract the value of elements from the POM without the need to navigate the objects.

This passage comes from the official website. Its main function is that it provides hooks that allow users to adjust the operation of the plug-in to meet their needs and can extract parameters from the pom file. This parameter can normally be extracted from the configration tag of the plugin

3. Install the written plug-in to the local warehouse

Excuting an order

mvn clean install

During the execution, the following exceptions may be reported

org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor (default-descriptor)

The reason for the error is that the maven-plugin-plugin version is not specified, so the default is 3.2, which does not fit the current code, so specify the version and add it to the pom file

 <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-plugin-plugin</artifactId>
                 <version>3.5</version>
             </plugin>
         </plugins>
     </build>

How to use custom plug-ins in the project

Take the plug-in of the sample project as an example, import it in pom.xml

 <build>
        <plugins>
            <plugin>
                <groupId>com.github.lybgeek</groupId>
                <artifactId>echo-maven-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                    <applicationName>springboot-echo</applicationName>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>echo</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Execute mvn clean package

image.png

Summarize

The maven plug-in can be regarded as a hook function of maven in the execution life cycle stage. If we want to trigger something during the compiling, packaging, installation, and deployment phases of the execution of maven, we can consider implementing a maven plug-in. For example, generating offline interface documents

In fact, the official website also provides a very detailed development guide for the development of the maven plug-in. If you are interested, you can check the following link

https://maven.apache.org/guides/plugin/guide-java-plugin-development.html

demo link

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-maven-plugin


linyb极客之路
344 声望193 粉丝