概述
记录开发 maven plugin 的步骤
创建 maven plugin 工程步骤
本地 maven 版本和 eclipse maven 版本需一致
本地版本和 eclipse 版本要一致,否则会出现莫名其妙的一系列错误。备注,我当前使用的 maven 版本是 3.3.3。
使用本地命令生成 maven plugin 项目
生成maven-hello-plugin
项目工程,
1 | $ mvn archetype:generate -DgroupId=org.shangyang.plugin -DartifactId=hello-maven-plugin -DarchetypeArtifactId=maven-archetype-mojo |
此步骤会从 repo.maven.org 官网上下载相关依赖文件和包,比较慢,最好使用代理或者翻墙。
将 maven plugin 工程导入 eclipse
用命令行执行 maven eclipse 构建
1
$ mvn eclipse:eclipse
此步骤是生成 maven 相关的 .project 信息
import -> exiting maven project
将 plugin 项目作为 maven project 导入
修改 pom.xml 配置文件
将
maven-plugin-api
修改为 3.0
根据使用本地命令生成 maven plugin 项目使用命令行的方式默认生成的工程模板是使用的 maven-plugin-api 2.0,而最新的 maven plugin 使用的是版本 3.0,这里我们根据最新版本来进行演示,所以,这里需要手动将其版本修改为 3.0打开 pom.xml,将对应内容修改为 3.0
1
2
3
4
5<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>1
2
3
4
5<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.0</version>
</dependency>添加 annotation dependencies
1
2
3
4
5
6
7
8<!-- dependencies to annotations -->
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
<scope>provided</scope>
</dependency>
</dependencies>完整的 pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.shangyang.plugin</groupId>
<artifactId>hello-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0-SNAPSHOT</version>
<name>maven-hello-plugin Maven Mojo</name>
<url>http://maven.apache.org</url>
<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>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
创建 Class GreeingMojo
删除默认生成的 MyMojo.java
创建 GreetingMojo.java
1 | package org.shangyang.plugin; |
- The annotation “@Mojo” is required and control how and when the mojo is executed.
- The execute method can throw two exceptions:
org.apache.maven.plugin.MojoExecutionException
if an unexpected problem occurs. Throwing this exception causes a “BUILD ERROR” message to be displayed.org.apache.maven.plugin.MojoFailureException
if an expected problem (such as a compilation failure) occurs. Throwing this exception causes a “BUILD FAILURE” message to be displayed.
构建 hello-maven-plugin
1 | $ mvn clean install |
clean: 会执行 clean
install: 编译,构建,并将 plugin 部署到本地 maven 库
中,相关日志如下1
2[INFO] Installing /Users/mac/workspace/mine/maven/plugin/hello-maven-plugin/target/hello-maven-plugin-1.0-SNAPSHOT.jar to /Users/mac/.m2/repository/org/shangyang/plugin/hello-maven-plugin/1.0-SNAPSHOT/hello-maven-plugin-1.0-SNAPSHOT.jar
[INFO] Installing /Users/mac/workspace/mine/maven/plugin/hello-maven-plugin/pom.xml to /Users/mac/.m2/repository/org/shangyang/plugin/hello-maven-plugin/1.0-SNAPSHOT/hello-maven-plugin-1.0-SNAPSHOT.pom
如果需要将 maven 部署到远程仓库中,需要执行mvn deploy
使用 mvn 命令运行该 plugin
命令格式为1
$ mvn groupId:artifactId:version:goal
goal
:就是@Mojo( name = "sayhi")
中标注的 name,这里是sayhi
1 | $ mvn org.shangyang.plugin:hello-maven-plugin:1.0-SNAPSHOT:sayhi |
相关日志输出,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.348 s
[INFO] Finished at: 2017-01-15T12:20:21+08:00
[INFO] Final Memory: 6M/156M
[INFO] ------------------------------------------------------------------------
执行过程会首先从本 maven 库中搜索 hello-maven-plugin 是否存在,若不存在再从远程 maven 库中搜索,找到该 plugin 以后便执行;可见,日志中输出了 Hello, world.
如何精简 mvn 执行命令
省略
version
当省略 version 以后,将会默认使用 maven 库中最新的 plugin 版本运行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16macdeMacBook-Pro:hello-maven-plugin mac$ mvn org.shangyang.plugin:hello-maven-plugin:sayhi
[INFO] Scanning for projects...
Downloading: https://repo1.maven.org/maven2/org/shangyang/plugin/hello-maven-plugin/maven-metadata.xml
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.500 s
[INFO] Finished at: 2017-01-15T14:23:23+08:00
[INFO] Final Memory: 7M/123M使用默认的
prefix
来简化执行命令
如果使用如下的格式来定义你的artifactId
的话,- maven-${prefix}-plugin
注意,这个是 maven 的保留 plugin 的命名格式,自定义 maven plugin 的时候,不能使用这种格式。 - ${prefix}-maven-plugin
用户自定可以使用的格式
那么 maven 可以自动推测 maven plugin 的 prefix,并使用该 prefix 来简化执行的 maven 命令;执行
mvn hello:sayhi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24$ mvn hello:sayhi
[INFO] Scanning for projects...
Downloading: https://repo1.maven.org/maven2/org/apache/portals/pluto/maven-metadata.xml
Downloading: https://repo1.maven.org/maven2/org/apache/portals/jetspeed-2/maven-metadata.xml
Downloading: https://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
Downloading: https://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloaded: https://repo1.maven.org/maven2/org/apache/portals/jetspeed-2/maven-metadata.xml (2 KB at 0.5 KB/sec)
Downloaded: https://repo1.maven.org/maven2/org/apache/portals/pluto/maven-metadata.xml (241 B at 0.1 KB/sec)
Downloaded: https://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml (20 KB at 6.9 KB/sec)
Downloaded: https://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml (13 KB at 3.4 KB/sec)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.494 s
[INFO] Finished at: 2017-01-15T14:45:56+08:00
[INFO] Final Memory: 10M/222M
[INFO] ------------------------------------------------------------------------
[ERROR] No plugin found for prefix 'hello' in the current project and in the plugin groups [org.apache.portals.pluto, org.apache.portals.jetspeed-2, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/mac/.m2/repository), alimaven (https://repo1.maven.org/maven2/)] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoPluginFoundForPrefixException但是报错,注意,这段日志
1
[ERROR] No plugin found for prefix 'hello' in the current project and in the plugin groups [org.apache.portals.pluto, org.apache.portals.jetspeed-2, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/mac/.m2/repository), alimaven (https://repo1.maven.org/maven2/)] -> [Help 1]
我们可以看到,mvn 在搜索本地库的时候,只会去检查[org.apache.portals.pluto, org.apache.portals.jetspeed-2, org.apache.maven.plugins, org.codehaus.mojo]这些 plugin groups,并没有去检查我们自定义的
org.shangyang.plugin
,所以执行不成功;我们需要自己的groupId
加入 maven 的本地配置中,修改本地 maven 的settings.xml
文件,将 groupIdorg.shangyang.plugin
加入1
2
3
4
5
6
7
8
9
10<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
<pluginGroup>org.apache.portals.pluto</pluginGroup>
<pluginGroup>org.apache.portals.jetspeed-2</pluginGroup>
<pluginGroup>org.shangyang.plugin</pluginGroup>
</pluginGroups>再次执行,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17macdeMacBook-Pro:hello-maven-plugin mac$ mvn hello:sayhi
[INFO] Scanning for projects...
Downloading: https://repo1.maven.org/maven2/org/shangyang/plugin/maven-metadata.xml
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.664 s
[INFO] Finished at: 2017-01-15T14:47:10+08:00
[INFO] Final Memory: 11M/222M
[INFO] ------------------------------------------------------------------------- maven-${prefix}-plugin
直接重命名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<project>
...
<build>
...
<plugins>
...
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.3</version>
<configuration>
...
<goalPrefix>somePrefix</goalPrefix>
</configuration>
</plugin>
</plugins>
</build>
</project>1
$ mvn somePrefix:goal
此部分参考 http://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html
如何进行 debug
使用 mvndebug 运行 plugin
1
2
3$ mvndebug org.shangyang.plugin:hello-maven-plugin:1.0-SNAPSHOT:sayhi
Preparing to Execute Maven in Debug Mode
Listening for transport dt_socket at address: 8000maven puglin service 会在 8000 端口监听;整个 debug 过程,不能停止
在 eclipse 中设置 debug configuration,配置 remote java application,使 Eclipse debug 远程服务。
进入 debug configuration, 右键点击新建 Remote Java application
填入相关信息如下
点击上图中的 debug 按钮,开始 debug
项目中引用自定义 maven plugin
我本地工程为/Users/mac/workspace/mine/maven/plugin/hello-world
将 maven plugin 加入 maven 构建阶段(build phase)的任何步骤
可加入的步骤参考maven 的构建阶段 maven build lifecycle
加入 compile 阶段
这里我们将 hello-maven-plugin 加入 hello-world 工程的 compile 阶段。
创建一个 maven project hello-world
,将hello-maven-plugin
加入compile
阶段,在 pom.xml 中加入如下片段1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<build>
<plugins>
<plugin>
<groupId>org.shangyang.plugin</groupId>
<artifactId>hello-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>sayhi</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
右键项目 -> Run As -> Maven Build… -> Goals: 输入 compile -> 执行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello-world 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default) @ hello-world ---
[INFO] Hello, world.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.477 s
[INFO] Finished at: 2017-01-15T15:14:43+08:00
[INFO] Final Memory: 9M/222M
[INFO] ------------------------------------------------------------------------
可以看到,输出中执行了自定义的hello-maven-plugin
并输出了 Hello, world.
TODO: 加入 generate sources 阶段
generate sources 生成代码唯一要注意的是,不能重复覆盖以前生成的代码,因为已经生成的代码很有可能人为更新过了;不过,避免也不复杂,能想到的就是,每次在生成对应文件以前,判断文件是否已经生成,若生成了,就不再重复生成。
参数 parameters
在 Mojo class 中自定义参数
1 | /** |
property
允许在 command line 执行的时候,通过 -D 指定参数 greeting 的值1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ mvn clean install
$ mvn -Dsayhi.greeting=MyGreetings org.shangyang.plugin:hello-maven-plugin:sayhi
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] Parameter greeting: MyGreetings
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.406 s
[INFO] Finished at: 2017-01-15T16:40:12+08:00
[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------通过
-Dsayhi.greeting=MyGreetings
指定了 greeting 的参数值为MyGreetings
,从日志中可以清楚的看到,设置成功。defaultValue
设置默认参数的值,可以设置 maven 内置的值,比如${project.version}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ mvn clean install
$ mvn org.shangyang.plugin:hello-maven-plugin:sayhi
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] Parameter greeting: Hello World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.343 s
[INFO] Finished at: 2017-01-15T16:44:13+08:00
[INFO] Final Memory: 6M/156M
[INFO] ------------------------------------------------------------------------
在 Mojo class 中可使用 maven 内置的参数值
Maven Parameters Expressions中定义了可以使用的 Maven 内置的参数值;不过初看,并不知道如何使用,这里,通过获得project
的version
参数为例,看是如何查询到project.version
的?
-> project -> 点击 MavenSession.getCurrentProject() -> getCurrentProject -> 点击 MavenProject;这里我们就进入了MavenProject的描述内容,这里我们可以看到所有 MavenProject 提供的 getXXX 方法,可以看到我们需要的getVersion()
方法;
其它可用的内置参数,可以通过如上的步骤查询得到。下面我们看看如何使用参数project.version
1
2
3
4
5
6
7
8
9
10
11
12
13/**
* The greeting to display.
*/
"sayhi.greeting", defaultValue = "${project.version}" ) ( property =
private String greeting;
public void execute() throws MojoExecutionException {
getLog().info("Hello, world.");
getLog().info("Parameter greeting: " + greeting);
}
重新构建1
$ mvn clean install
执行 plugin1
2
3$ mvn org.shangyang.plugin:hello-maven-plugin:sayhi
# 或者执行如下命令,(要执行成功,参考前面的如何简化的部分)
$ mvn hello:sayhi
输出日志1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-hello-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default-cli) @ hello-maven-plugin ---
[INFO] Hello, world.
[INFO] Parameter greeting: 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.740 s
[INFO] Finished at: 2017-01-15T16:35:59+08:00
[INFO] Final Memory: 9M/156M
[INFO] ------------------------------------------------------------------------
可见打印出的${project.version}
为了1.0-SNAPSHOT
。
通过 pom.xml 设置参数值
在引用 hello-maven-plugin 的hello-world
maven 项目中,通过 pom.xml 设置对应的参数值1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<build>
<plugins>
<plugin>
<groupId>org.shangyang.plugin</groupId>
<artifactId>hello-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<greeting>Welcome</greeting>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>sayhi</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
在hello-world
工程中执行 maven 构建命令 compile, 输出日志如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello-world 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- hello-maven-plugin:1.0-SNAPSHOT:sayhi (default) @ hello-world ---
[INFO] Hello, world.
[INFO] Parameter greeting: Welcome
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.534 s
[INFO] Finished at: 2017-01-15T16:48:44+08:00
[INFO] Final Memory: 8M/156M
[INFO] ------------------------------------------------------------------------
可见 Parameter greeting: Welcome 输出的值为 Welcome
Boolean、Number、Dates、Files、URLS..
参考教程 http://maven.apache.org/guides/plugin/guide-java-plugin-development.html
mvn 常用的构建命令
命令 | 描述 |
---|---|
compile | Compiles the Java code for the plugin and builds the plugin descriptor |
test | Runs the plugin’s unit tests |
package | Builds the plugin jar |
install | Installs the plugin jar in the local repository |
deploy | Deploys the plugin jar to the remote repository |
更全的构建阶段参考 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
References
官网 user guide,
http://maven.apache.org/guides/plugin/guide-java-plugin-development.html
debug,
http://stackoverflow.com/questions/2973888/debug-a-maven-plugins-execution-in-a-maven-web-project
http://www.ibm.com/developerworks/library/os-ecbug/
maven build lifecycle,
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
TODO
可以将以前用来生成 mybatis bean 的代码写成 maven plugin 的方式方便使用。