自定義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