Maven插件

Maven 插件

参考资料:

http://maven.apache.org/components/plugins
https://blog.csdn.net/HaosCoder/article/details/79524629
https://www.yiibai.com/maven/maven_plugins.html

Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成。

创建 jar 文件

创建 war 文件

编译代码文件

进行代码单元测试

创建项目文档

创建项目报告

一个插件通常提供了一组目标,可使用以下语法来执行:

mvn [plugin-name]:[goal-name]

例如,一个 Java 项目可以使用 Maven 编译器插件来编译目标,通过运行以下命令编译

mvn compiler:compile

插件类型

类型 描述
构建插件 在生成过程中执行,并在 pom.xml 中的<build/> 元素进行配置
报告插件 在网站生成期间执行,在 pom.xml 中的 <reporting/> 元素进行配置

常用插件

Maven官方有两个插件列表:

第一个列表的GroupId为org.apache.maven.plugins,这里的插件最为成熟,具体地址为:http://maven.apache.org/plugins/index.html

第二个列表的GroupId为org.codehaus.mojo,这里的插件没有那么核心,但也有不少十分有用,其地址为:http://mojo.codehaus.org/plugins.html

以下是一些常见的插件列表:

插件 描述
clean 编译后的清理目标,删除目标目录
compiler 编译 Java 源文件
surefile 运行JUnit单元测试,创建测试报告
jar 从当前项目构建 JAR 文件
war 从当前项目构建 WAR 文件
javadoc 产生用于该项目的 Javadoc
antrun 从构建所述的任何阶段运行一组 Ant 任务

插件使用

用户可以通过两种方式调用Maven插件目标。

第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已。

例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定,因此命令mvn compile实际上是先定位到compile这一生命周期阶段,然后再根据绑定关系调用maven-compiler-plugin的compile目标。

第二种方式是直接在命令行指定要执行的插件目标。

例如mvn archetype:generate 就表示调用maven-archetype-plugin的generate目标,这种带冒号的调用方式与生命周期无关。

插件

  • maven-jar-plugin

https://www.cnblogs.com/xsblog/p/9311316.html

  • maven-antrun-plugin

    maven-antrun-plugin能让用户在Maven项目中运行Ant任务。用户可以直接在该插件的配置以Ant的方式编写Target,然后交给该插件的run目标去执行。

    在一些由Ant往Maven迁移的项目中,该插件尤其有用。

    此外当你发现需要编写一些自定义程度很高的任务,同时又觉得Maven不够灵活时,也可以以Ant的方式实现之。maven-antrun-plugin的run目标通常与生命周期绑定运行

  • maven-archetype-plugin
    http://maven.apache.org/archetype/maven-archetype-plugin/

    Archtype指项目的骨架,Maven初学者最开始执行的Maven命令可能就是mvn archetype:generate,这实际上就是让maven-archetype-plugin生成一个很简单的项目骨架,帮助开发者快速上手。

    可能也有人看到一些文档写了mvn archetype:create,但实际上create目标已经被弃用了,取而代之的是generate目标,该目标使用交互式的方式提示用户输入必要的信息以创建项目,体验更好。

    maven-archetype-plugin还有一些其他目标帮助用户自己定义项目原型,例如你由一个产品需要交付给很多客户进行二次开发,你就可以为他们提供一个Archtype,帮助他们快速上手。

  • maven-assembly-plugin

    maven-assembly-plugin的用途是制作项目分发包,该分发包可能包含了项目的可执行文件、源代码、readme、平台脚本等等。

    maven-assembly-plugin支持各种主流的格式如zip、tar.gz、jar和war等,具体打包哪些文件是高度可控的。

    例如用户可以按文件级别的粒度、文件集级别的粒度、模块级别的粒度、以及依赖级别的粒度控制打包,此外,包含和排除配置也是支持的。

    maven-assembly-plugin要求用户使用一个名为assembly.xml的元数据文件来表述打包,它的single目标可以直接在命令行调用,也可以被绑定至生命周期

  • maven-dependency-plugin

    maven-dependency-plugin最大的用途是帮助分析项目依赖

    dependency:list能够列出项目最终解析到的依赖列表

    dependency:tree能进一步的描绘项目依赖树

    dependency:analyze可以告诉你项目依赖潜在的问题

    如果你有直接使用到的却未声明的依赖,该目标就会发出警告。

    maven-dependency-plugin还有很多目标帮助你操作依赖文件,例如dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。

  • maven-enforcer-plugin

    在一个稍大一点的组织或团队中,你无法保证所有成员都熟悉Maven,那他们做一些比较愚蠢的事情就会变得很正常。

例如给项目引入了外部的SNAPSHOT依赖而导致构建不稳定,使用了一个与大家不一致的Maven版本而经常抱怨构建出现诡异问题。

maven-enforcer-plugin能够帮助你避免之类问题,它允许你创建一系列规则强制大家遵守,包括设定Java版本、设定Maven版本、禁止某些依赖、禁止SNAPSHOT依赖。

只要在一个父POM配置规则,然后让大家继承,当规则遭到破坏的时候,Maven就会报错。

除了标准的规则之外,你还可以扩展该插件,编写自己的规则。maven-enforcer-plugin的enforce目标负责检查规则,它默认绑定到生命周期的validate阶段。

  • maven-help-plugin

    maven-help-plugin是一个小巧的辅助工具。

    最简单的help:system可以打印所有可用的环境变量和Java系统属性。

    help:effective-pom和help:effective-settings最为有用,它们分别打印项目的有效POM和有效settings,有效POM是指合并了所有父POM(包括Super POM)后的XML,

    当你不确定POM的某些信息从何而来时,就可以查看有效POM。

    有效settings同理,特别是当你发现自己配置的settings.xml没有生效时,就可以用help:effective-settings来验证。

    此外,maven-help-plugin的describe目标可以帮助你描述任何一个Maven插件的信息,还有all-profiles目标和active-profiles目标帮助查看项目的Profile。

  • maven-release-plugin

    maven-release-plugin的用途是帮助自动化项目版本发布,它依赖于POM中的SCM信息。

    release:prepare用来准备版本发布,具体的工作包括检查是否有未提交代码、检查是否有SNAPSHOT依赖、升级项目的SNAPSHOT版本至RELEASE版本、为项目打标签等等。

    release:perform则是签出标签中的RELEASE源码,构建并发布。版本发布是非常琐碎的工作,它涉及了各种检查,而且由于该工作仅仅是偶尔需要,因此手动操作很容易遗漏一些细节。

    maven-release-plugin让该工作变得非常快速简便,不易出错。maven-release-plugin的各种目标通常直接在命令行调用,因为版本发布显然不是日常构建生命周期的一部分。

  • 默认的编译插件maven-compiler-plugin
  • 默认的打包插件maven-jar-plugin

例子

它支持各种打包文件格式,包括zip、tar.gz、tar.bz2等等,通过一个打包描述文件(该例中是src/main/assembly.xml),它能够帮助用户选择具体打包哪些文件集合、依赖、模块、和甚至本地仓库文件,每个项的具体打包路径用户也能自由控制。如下就是对应上述需求的打包描述文件src/main/assembly.xml:

<assembly>
  <id>bin</id>
  <formats>
    <format>zip</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <useProjectArtifact>true</useProjectArtifact>
      <outputDirectory>lib</outputDirectory>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>README.txt</include>
      </includes>
    </fileSet>
    <fileSet>
      <directory>src/main/scripts</directory>
      <outputDirectory>/bin</outputDirectory>
      <includes>
        <include>run.sh</include>
        <include>run.bat</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>

最后,我们需要配置maven-assembly-plugin使用打包描述文件,并绑定生命周期阶段使其自动执行打包操作:

默认情况下,maven-assembly-plugin内置了几个可以用的assembly descriptor:

  • bin : 类似于默认打包,会将bin目录下的文件打到包中
  • jar-with-dependencies : 会将所有依赖都解压打包到生成物中
  • src :只将源码目录下的文件打包
  • project : 将整个project资源打包
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <configuration>
      <descriptors>
        <descriptor>src/main/assembly/assembly.xml</descriptor>
      </descriptors>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  • maven-surefire-plugin 打包时跳过单元测试
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

mvn package -Dmaven.test.skip=true
如果单元测试中有输出中文,eclipse的控制台里中文可能会变成乱码输出,也可以通过这个插件解决,参考配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <forkMode>once</forkMode>
        <argLine>-Dfile.encoding=UTF-8</argLine>
    </configuration>
</plugin>
  • maven-dependency-plugin

    https://blog.csdn.net/yyoc97/article/details/77689531

    自动拷贝jar包到target目录, goal 有<goal> 为copy,和 copy-dependencies, 区别是copy是选择打包哪些依赖, copy-dependencies是排除哪些依赖

    有用命令: mvn dependency:tree 依赖树

1. copy
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>3.0.1</version>
  <configuration>
    <artifactItems>
      <artifactItem>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
      </artifactItem>
    </artifactItems>
    <outputDirectory>target/lib</outputDirectory>
  </configuration>
  <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>copy</goal>
        </goals>
      </execution>
  </executions>
</plugin>
2. copy-dependencies
<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>compile</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>target/lib</outputDirectory>
                <!-- 表示是否不包含间接依赖的包 -->
                <excludeTransitive>false</excludeTransitive>
                <!-- 表示复制的jar文件去掉版本信息 -->
                <stripVersion>true</stripVersion>
                <!-- 排除打包 -->
                <excludeArtifactIds>
                    spring-boot-devtools,junit
                </excludeArtifactIds>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>
  • maven-shade-plugin

打超级Jar包, 它包含所有的依赖 jar 包。也可以使用该插件解决包冲突问题

 <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>cn.dubby.undertow.demo.HelloWorldServer</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

推荐阅读更多精彩内容