很想尝试一下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));
}
}
网友评论