很想尝试一下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
模板
4.0.0
zhouf.plugin
first-maven-plugin
1.0-SNAPSHOT
maven-plugin
first-maven-plugin Maven Plugin
http://maven.apache.org
UTF-8
org.apache.maven
maven-plugin-api
2.0
org.apache.maven.plugin-tools
maven-plugin-annotations
3.2
provided
org.codehaus.plexus
plexus-utils
3.0.8
junit
junit
4.8.2
test
org.apache.maven.plugins
maven-plugin-plugin
3.2
first-maven-plugin
true
mojo-descriptor
descriptor
help-goal
helpmojo
run-its
org.apache.maven.plugins
maven-invoker-plugin
1.7
true
${project.build.directory}/it
*/pom.xml
verify
${project.build.directory}/local-repo
src/it/settings.xml
clean
test-compile
integration-test
install
integration-test
verify
在生成模板里,有些组件的版本选择比较早,可以手动调整为新的版本
org.apache.maven
maven-plugin-api
3.8.2
org.apache.maven.plugin-tools
maven-plugin-annotations
3.6.0
provided
...
org.apache.maven.plugins
maven-plugin-plugin
3.6.1
2、执行编译
mvn clean compile
执行后会出现如下错误
-source 1.5 中不支持 try-with-resources
(请使用 -source 7 或更高版本以启用 try-with-resources)
修改properties,加入编译版本为8
UTF-8
8
8
修改后再次编译
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
zhouf.plugin
如果不想修改这个文件,也可以将项目
设置为
[org.apache.maven.plugins, org.codehaus.mojo]
中的一个,系统会默认加载上面两个group,但不推荐这样做
修改项目中的pom.xml
文件,将
设置为调用前缀
org.apache.maven.plugins
maven-plugin-plugin
3.4
first
true
然后就可以使用如下命令调用此插件了
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
文件中生成有访问前缀,前缀
可以多个,指向调用的
first-maven-plugin Maven Plugin
first-maven-plugin
first-maven-plugin
first-maven-plugin Maven Plugin
first
first-maven-plugin
4、调用测试
在pom.xml
文件中有一段
run-its
org.apache.maven.plugins
maven-invoker-plugin
1.7
true
${project.build.directory}/it
*/pom.xml
verify
${project.build.directory}/local-repo
src/it/settings.xml
clean
test-compile
integration-test
install
integration-test
verify
执行
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
org.apache.maven.plugins
maven-invoker-plugin
3.2.1
验证通过,使用如下命令做集成测试
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版本
- 修改相关组件版本
org.apache.maven
maven-plugin-api
3.8.2
org.apache.maven.plugin-tools
maven-plugin-annotations
3.6.0
provided
...
org.apache.maven.plugins
maven-plugin-plugin
3.6.1
...
run-its
org.apache.maven.plugins
maven-invoker-plugin
3.2.1
...
附:开发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));
}
}