美文网首页Maven
Maven 插件编写记录

Maven 插件编写记录

作者: zhouf_cq | 来源:发表于2021-08-26 21:18 被阅读0次

    很想尝试一下Maven插件编写,之前试过许多的文档,总没能成功,也参考了《Maven实战》上的内容,那上面的内容有点早,现在生成代码中goal都已被标注为废弃

    /**
     * Goal which touches a timestamp file.
     *
     * @deprecated Don't use!
     */
    

    今天总算是静下心来弄好了,从早上4点过开始,到现在整理好这篇文档,弄好之后发现也不难,可能就是没有指导独自摸索的过程比较痛苦,在此记录一下。如果这篇文档能帮助到其它人,就不枉费这次分享

    说明:

    本机使用jdk11,在编译插件时报错,后来降级为jdk8后正常,估计是在适配jdk11方面还没有处理好,这也是踩过的坑

    1、使用mvn创建插件项目

    mvn archetype:generate
    

    此处会提示有10种类型可选择,插件应该是第3项maven-archetype-plugin,如果需要加入过滤,则可以filter参数,如下语句

    mvn archetype:generate -Dfilter=archetype-plugin
    

    也可以直接使用命令行指定项目类型

    mvn archetype:generate -DarchetypeArtifactId=maven-archetype-plugin
    

    需要注意的是,直接用命令行指定项目类型后,默认创建的版本为1.0版本,会提示project created from Old (1.x) Archetype

    创建工程的其他信息如下

    Confirm properties configuration:
    groupId: zhouf.plugin
    artifactId: first-maven-plugin
    version: 1.0-SNAPSHOT
    package: zhouf.plugin
     Y: :
    

    生成如下pom.xml模板

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>zhouf.plugin</groupId>
      <artifactId>first-maven-plugin</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>maven-plugin</packaging>
    
      <name>first-maven-plugin Maven Plugin</name>
    
      <!-- FIXME change it to the project's website -->
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-plugin-api</artifactId>
          <version>2.0</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven.plugin-tools</groupId>
          <artifactId>maven-plugin-annotations</artifactId>
          <version>3.2</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.codehaus.plexus</groupId>
          <artifactId>plexus-utils</artifactId>
          <version>3.0.8</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.8.2</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-plugin-plugin</artifactId>
            <version>3.2</version>
            <configuration>
              <goalPrefix>first-maven-plugin</goalPrefix>
              <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
            </configuration>
            <executions>
              <execution>
                <id>mojo-descriptor</id>
                <goals>
                  <goal>descriptor</goal>
                </goals>
              </execution>
              <execution>
                <id>help-goal</id>
                <goals>
                  <goal>helpmojo</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <profiles>
        <profile>
          <id>run-its</id>
          <build>
    
            <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-invoker-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                  <debug>true</debug>
                  <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
                  <pomIncludes>
                    <pomInclude>*/pom.xml</pomInclude>
                  </pomIncludes>
                  <postBuildHookScript>verify</postBuildHookScript>
                  <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
                  <settingsFile>src/it/settings.xml</settingsFile>
                  <goals>
                    <goal>clean</goal>
                    <goal>test-compile</goal>
                  </goals>
                </configuration>
                <executions>
                  <execution>
                    <id>integration-test</id>
                    <goals>
                      <goal>install</goal>
                      <goal>integration-test</goal>
                      <goal>verify</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
            </plugins>
    
          </build>
        </profile>
      </profiles>
    </project>
    
    

    在生成模板里,有些组件的版本选择比较早,可以手动调整为新的版本

    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>3.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.plugin-tools</groupId>
        <artifactId>maven-plugin-annotations</artifactId>
        <version>3.6.0</version>
        <scope>provided</scope>
    </dependency>
    
    ...
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.6.1</version>
    

    2、执行编译

    mvn clean compile
    

    执行后会出现如下错误

     -source 1.5 中不支持 try-with-resources
      (请使用 -source 7 或更高版本以启用 try-with-resources)
    

    修改properties,加入编译版本为8

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    

    修改后再次编译

    mvn clean compile
    

    编译通过后,执行install

    mvn install
    

    也可以用一条语句进行

    mvn clean install
    

    执行成功

    如果不希望输出[INFO]消息,可以使用-q参数
    mvn clean install -q

    3、运行

    运行命令格式如下

    mvn groupId:artifactId:version:goal
    

    调用命令如下

    mvn zhouf.plugin:first-maven-plugin:1.0-SNAPSHOT:touch
    

    其中version可省

    mvn zhouf.plugin:first-maven-plugin:touch
    

    执行完后,会有target\touch.txt文件生成

    配置简略调用

    如果需要调用时使用更为简单的方法,可配置${user.home}/.m2/settings.xml文件,加入pluginGroup

    <pluginGroups>
        <!-- pluginGroup
            | Specifies a further group identifier to use for plugin lookup.
        <pluginGroup>com.your.plugins</pluginGroup>
        -->
        <pluginGroup>zhouf.plugin</pluginGroup>
    </pluginGroups>
    

    如果不想修改这个文件,也可以将项目<groupId>设置为[org.apache.maven.plugins, org.codehaus.mojo]中的一个,系统会默认加载上面两个group,但不推荐这样做

    修改项目中的pom.xml文件,将<goalPrefix>设置为调用前缀

    <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-plugin-plugin</artifactId>
            <version>3.4</version>
            <configuration>
              <goalPrefix>first</goalPrefix>
              <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
            </configuration>
    

    然后就可以使用如下命令调用此插件了

    mvn clean install
    mvn first:touch
    

    编译后,会在本地仓库中生成

    └─zhouf
        └─plugin
            │  maven-metadata-local.xml
            │  resolver-status.properties
            │
            └─first-maven-plugin
                │  maven-metadata-local.xml
                │  resolver-status.properties
                │
                └─1.0-SNAPSHOT
                        first-maven-plugin-1.0-SNAPSHOT.jar
                        first-maven-plugin-1.0-SNAPSHOT.pom
                        maven-metadata-local.xml
                        _remote.repositories
    

    其中plugin\maven-metadata-local.xml文件中生成有访问前缀,前缀<prefix>可以多个,指向调用的<artifactId>

    <?xml version="1.0" encoding="UTF-8"?>
    <metadata>
      <plugins>
        <plugin>
          <name>first-maven-plugin Maven Plugin</name>
          <prefix>first-maven-plugin</prefix>
          <artifactId>first-maven-plugin</artifactId>
        </plugin>
        <plugin>
          <name>first-maven-plugin Maven Plugin</name>
          <prefix>first</prefix>
          <artifactId>first-maven-plugin</artifactId>
        </plugin>
      </plugins>
    </metadata>
    

    4、调用测试

    pom.xml文件中有一段<profile>

    <profiles>
        <profile>
          <id>run-its</id>
          <build>
    
            <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-invoker-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                  <debug>true</debug>
                  <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
                  <pomIncludes>
                    <pomInclude>*/pom.xml</pomInclude>
                  </pomIncludes>
                  <postBuildHookScript>verify</postBuildHookScript>
                  <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
                  <settingsFile>src/it/settings.xml</settingsFile>
                  <goals>
                    <goal>clean</goal>
                    <goal>test-compile</goal>
                  </goals>
                </configuration>
                <executions>
                  <execution>
                    <id>integration-test</id>
                    <goals>
                      <goal>install</goal>
                      <goal>integration-test</goal>
                      <goal>verify</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
            </plugins>
    
          </build>
        </profile>
    </profiles>
    

    执行

    mvn verify -Prun-its
    

    时报如下错误

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-invoker-plugin:1.7:verify (integration-test) on project second-maven-plugin: 1 build failed. See console output above for details. -> [Help 1]
    

    将版本由1.7改为3.2.1

    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-invoker-plugin</artifactId>
    <version>3.2.1</version>
    

    验证通过,使用如下命令做集成测试

    mvn integration-test -Prun-its
    

    成功输出

    [INFO] Building: simple-it\pom.xml
    [INFO] run post-build script verify.groovy
    [INFO]           simple-it\pom.xml ................................ SUCCESS (4.2 s)
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    

    5、小结

    • 注意jdk版本
    • 修改相关组件版本
    <dependencies>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-plugin-api</artifactId>
          <version>3.8.2</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven.plugin-tools</groupId>
          <artifactId>maven-plugin-annotations</artifactId>
          <version>3.6.0</version>
          <scope>provided</scope>
        </dependency>
        ...
    </dependencies>
    
    
    
    <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-plugin-plugin</artifactId>
            <version>3.6.1</version>
            ...
          </plugin>
        </plugins>
      </build>
      <profiles>
        <profile>
          <id>run-its</id>
          <build>
    
            <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-invoker-plugin</artifactId>
                <version>3.2.1</version>
                ...
              </plugin>
            </plugins>
    
          </build>
        </profile>
      </profiles>
    

    附:开发Mojo补充

    在编写mojo类时,可使用如下变量

    变量 含义 默认值
    ${project.build.sourceDirectory} 项目的主源码目录 src/main/java/.
    ${project.build.testSourceDirectory} 项目的测试源码目录 /src/test/java/.
    ${project.build.directory} 项目构建输出目录 target/.
    ${project.build.outputDirectory} 项目主代码编译输出目录 target/classes/.
    ${project.build.testOutputDirectory} 项目测试代码编译输出目录 target/testclasses/.
    ${project.groupId} 项目的groupId
    ${project.artifactId} 项目的artifactId.
    ${project.version} 项目的version,同${version}等价
    ${project.build.finalName} 项目打包输出文件的名称 ${project.artifactId}${project.version}.

    Mojo类代码参考

    @Mojo( name = "info", defaultPhase = LifecyclePhase.PROCESS_SOURCES )
    public class FirstMojo
        extends AbstractMojo
    {
        @Parameter(defaultValue = "${project.basedir}")
        private File baseDir;
    
        @Parameter(defaultValue = "${project.build.sourceDirectory}")
        private File sourceDirectory;
    
        @Parameter(defaultValue = "${project.build.testSourceDirectory}")
        private File testSourceDirectory;
    
        @Parameter(defaultValue = "${project.build.directory}")
        private File directory;
    
        @Parameter(defaultValue = "${project.build.outputDirectory}")
        private File outputDirectory;
    
        @Parameter(defaultValue = "${project.build.testOutputDirectory}")
        private File testOutputDirectory;
    
        @Parameter(defaultValue = "${project.build.finalName}")
        private String finalName;
    
        @Parameter(defaultValue = "${project.groupId}")
        private String groupId;
    
        @Parameter(defaultValue = "${project.artifactId}")
        private String artifactId;
    
        @Parameter(defaultValue = "${project.version}")
        private String version;
    
        public void execute()
            throws MojoExecutionException
        {
            getLog().info( "------------------------------------------------------------------------" );
            getLog().info(String.format(">>> %-25s %s", "baseDir",baseDir.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "sourceDirectory",sourceDirectory.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "testSourceDirectory",testSourceDirectory.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "directory",directory.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "outputDirectory",outputDirectory.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "testOutputDirectory",testOutputDirectory.getAbsolutePath()));
            getLog().info(String.format(">>> %-25s %s", "finalName",finalName));
            getLog().info(String.format(">>> %-25s %s", "groupId",groupId));
            getLog().info(String.format(">>> %-25s %s", "artifactId",artifactId));
            getLog().info(String.format(">>> %-25s %s", "version",version));
        }
    }
    

    相关文章

      网友评论

        本文标题:Maven 插件编写记录

        本文链接:https://www.haomeiwen.com/subject/rjzuiltx.html