如何开发 Maven Plugins

概述

记录开发 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

  1. 用命令行执行 maven eclipse 构建

    1
    $ mvn eclipse:eclipse

    此步骤是生成 maven 相关的 .project 信息

  2. import -> exiting maven project
    将 plugin 项目作为 maven project 导入

修改 pom.xml 配置文件

  1. 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>
  2. 添加 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>
  3. 完整的 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package org.shangyang.plugin;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;

/**
- Says "Hi" to the user.
*
*/
@Mojo( name = "sayhi")
public class GreetingMojo extends AbstractMojo
{
public void execute() throws MojoExecutionException
{
getLog().info( "Hello, world." );
}
}
  • 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 执行命令

  1. 省略version
    当省略 version 以后,将会默认使用 maven 库中最新的 plugin 版本运行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    macdeMacBook-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
  2. 使用默认的prefix来简化执行命令
    如果使用如下的格式来定义你的artifactId的话,

    1. maven-${prefix}-plugin
      注意,这个是 maven 的保留 plugin 的命名格式,自定义 maven plugin 的时候,不能使用这种格式。
    2. ${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文件,将 groupId org.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
    17
    macdeMacBook-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] ------------------------------------------------------------------------
  3. 直接重命名

    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
  4. 此部分参考 http://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html

如何进行 debug

  1. 使用 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: 8000

    maven puglin service 会在 8000 端口监听;整个 debug 过程,不能停止

  2. 在 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
2
3
4
5
6
7
8
9
10
11
12
13
/**
* The greeting to display.
*/
@Parameter( property = "sayhi.greeting", defaultValue = "Hello World!" )
private String greeting;

public void execute() throws MojoExecutionException {

getLog().info("Hello, world.");

getLog().info("Parameter greeting: " + greeting);

}
  • 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 内置的参数值;不过初看,并不知道如何使用,这里,通过获得projectversion参数为例,看是如何查询到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.
*/
@Parameter( property = "sayhi.greeting", defaultValue = "${project.version}" )
private String greeting;

public void execute() throws MojoExecutionException {

getLog().info("Hello, world.");

getLog().info("Parameter greeting: " + greeting);

}

重新构建

1
$ mvn clean install

执行 plugin

1
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 的方式方便使用。