自定义 maven 插件
自定义maven插件
maven的价值除了它的版本管理,依赖管理,以及规范化java代码结构之外,它丰富且易用的插件也是非常重要的特性.下面我们就来自定义一个maven插件.来进一步认识maven.
maven插件开发流程
- 创建maven插件项目
- 编写maven目标(goal)
- 提供maven扩展配置点
- 实现目标行为
- 错误处理和日志
- 测试插件
实现
- 创建maven插件项目
创建maven插件项目与普通的maven类似,只是使用的模板不同,这里使用官方的插件模板:
mvn archetype:generate
然后选择:3: internal -> org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.)
项目层级结构:
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>com.ll</groupId>
<artifactId>loc-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>loc-maven-plugin Maven Plugin</name>
<!-- FIXME change it to the project's website -->
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.0</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-invoker-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<postBuildHookScript>verify</postBuildHookScript>
<goals>
<goal>install</goal>
</goals>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
插件项目与普通maven项目的核心区别在于pom.xml中:
1 packaing是:maven-plugin
2 依赖maven-plugin-api中定义进行maven插件实现
这里要注意:
maven-*-plugin的artifactId名称被官方保留,自己使用时会报错.
修改maven-plugin-api版本为3.0
删除非必要的依赖其插件配置
- 代码编写
代码编写:
1 自定义类继承org.apache.maven.plugin.AbstractMojo
2 实现execute()方法
3 提供@goal标注
@goal是触发execute()方法执行的自定义标识
参数定义可以使用我参考资料里的注释方式,也可以使用注解方式.实际注释方式更简洁:
注释方式:
/**
* @parameter property = "project.basedir"
* @required
* @readonly
*/
private File basedir;
注解方式:
1 需要在pom.xml中引入注解依赖
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
<scope>provided</scope>
</dependency>
使用方式
@Parameter( defaultValue = "${project.build.directory}", property = "outputDir", required = true )
private File outputDirectory;
- 使用
代码编写完毕后,执行mvn clean install将插件安装到本地,这样其他项目就可以引用此插件.
引用方式:
pom.xml中添加如下插件配置
<build>
<plugins>
<plugin>
<groupId>com.ll</groupId>
<artifactId>loc-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>count</goal>
</goals>
</execution>
</executions>
<configuration>
<incloude>java</incloude>
<incloude>sql</incloude>
</configuration>
</plugin>
</plugins>
</build>
实际执行就可以触发自定义插件的使用
- 扩展
实际的代码中使用了集成测试插件:maven-invoker-plugin.它是专门进行插件测试的插件.它的使用需要将使用插件的项目放到插件项目下的src/it目录下(这个目录是默认目录,可以配置).实际插件pom.xml配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<postBuildHookScript>verify</postBuildHookScript>
<goals>
<goal>install</goal>
</goals>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
postBuildHookScript定义测试grooy脚本,groovy脚本如下:
File file = new File( basedir, "build.log" );
def countMain = false
def countTest = false
file.eachLine {
if (it.contains("files size: 1 lines num: 7"))
countMain = true;
if (it.contains("files size: 0 lines num: 0"))
countTest = true;
}
if(!countMain) {
throw new RuntimeException("incorrect src/main/java count info");
}
if(!countTest) {
throw new RuntimeException("incorrect src/test/java count info");
}
内容很简单,就是预期的测试输出内容定义,符合预期则提示成功,不符合则输出失败.
最终项目层级结构:
测试
在插件项目下执行: mvn clean install
执行效果:
D:\workfile\jdk\jdk11.0.13\bin\java.exe -Dmaven.multiModuleProjectDirectory=D:\git_repo\demo\loc-maven-plugin "-Dmaven.home=D:\workfile\ide\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3" "-Dclassworlds.conf=D:\workfile\ide\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\bin\m2.conf" "-Dmaven.ext.class.path=D:\workfile\ide\IntelliJ IDEA 2021.2\plugins\maven\lib\maven-event-listener.jar" "-javaagent:D:\workfile\ide\IntelliJ IDEA 2021.2\lib\idea_rt.jar=50816:D:\workfile\ide\IntelliJ IDEA 2021.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\workfile\ide\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\boot\plexus-classworlds-2.6.0.jar;D:\workfile\ide\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\boot\plexus-classworlds.license" org.codehaus.classworlds.Launcher -Didea.version=2021.2 clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.ll:loc-maven-plugin >-----------------------
[INFO] Building loc-maven-plugin Maven Plugin 1.0-SNAPSHOT
[INFO] ----------------------------[ maven-plugin ]----------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ loc-maven-plugin ---
[INFO] Deleting D:\git_repo\demo\loc-maven-plugin\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ loc-maven-plugin ---
[INFO] Using 'utf8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\git_repo\demo\loc-maven-plugin\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ loc-maven-plugin ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to D:\git_repo\demo\loc-maven-plugin\target\classes
[INFO]
[INFO] --- maven-plugin-plugin:3.2:descriptor (default-descriptor) @ loc-maven-plugin ---
[INFO] Using 'utf8' encoding to read mojo metadata.
[INFO] Applying mojo extractor for language: java
[INFO] Mojo extractor for language: java found 1 mojo descriptors.
[INFO] Applying mojo extractor for language: bsh
[INFO] Mojo extractor for language: bsh found 0 mojo descriptors.
[INFO] Applying mojo extractor for language: java-annotations
[INFO] Mojo extractor for language: java-annotations found 0 mojo descriptors.
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ loc-maven-plugin ---
[INFO] Using 'utf8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\git_repo\demo\loc-maven-plugin\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ loc-maven-plugin ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ loc-maven-plugin ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ loc-maven-plugin ---
[INFO] Building jar: D:\git_repo\demo\loc-maven-plugin\target\loc-maven-plugin-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-plugin-plugin:3.2:addPluginArtifactMetadata (default-addPluginArtifactMetadata) @ loc-maven-plugin ---
[INFO]
[INFO] --- maven-invoker-plugin:3.1.0:install (integration-test) @ loc-maven-plugin ---
[INFO] Installing D:\git_repo\demo\loc-maven-plugin\pom.xml to D:\repository\com\ll\loc-maven-plugin\1.0-SNAPSHOT\loc-maven-plugin-1.0-SNAPSHOT.pom
[INFO] Installing D:\git_repo\demo\loc-maven-plugin\target\loc-maven-plugin-1.0-SNAPSHOT.jar to D:\repository\com\ll\loc-maven-plugin\1.0-SNAPSHOT\loc-maven-plugin-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-invoker-plugin:3.1.0:run (integration-test) @ loc-maven-plugin ---
[INFO] Building: count-demo\pom.xml
[INFO] run post-build script verify.groovy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass (file:/D:/repository/org/codehaus/groovy/groovy-all/2.4.8/groovy-all-2.4.8.jar) to method java.lang.Object.finalize()
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.reflection.CachedClass
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[INFO] count-demo\pom.xml ............................... SUCCESS (2.7 s)
[INFO] -------------------------------------------------
[INFO] Build Summary:
[INFO] Passed: 1, Failed: 0, Errors: 0, Skipped: 0
[INFO] -------------------------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ loc-maven-plugin ---
[INFO] Installing D:\git_repo\demo\loc-maven-plugin\target\loc-maven-plugin-1.0-SNAPSHOT.jar to D:\repository\com\ll\loc-maven-plugin\1.0-SNAPSHOT\loc-maven-plugin-1.0-SNAPSHOT.jar
[INFO] Installing D:\git_repo\demo\loc-maven-plugin\pom.xml to D:\repository\com\ll\loc-maven-plugin\1.0-SNAPSHOT\loc-maven-plugin-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.726 s
[INFO] Finished at: 2022-03-12T16:02:19+08:00
[INFO] ------------------------------------------------------------------------
Process finished with exit code 0