写点什么

Maven 实战(八)——常用 Maven 插件介绍(下)

2011 年 5 月 09 日

我们都知道 Maven 本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由 maven- compiler-plugin 完成的。进一步说,每个任务对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如 maven- compiler-plugin 的 compile 目标用来编译位于src/main/java/目录下的主源码,testCompile 目标用来编译位于src/test/java/目录下的测试源码。

用户可以通过两种方式调用 Maven 插件目标。第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已,例如 Maven 默认将 maven-compiler-plugin 的 compile 目标与 compile 生命周期阶段绑定,因此命令mvn compile实际上是先定位到 compile 这一生命周期阶段,然后再根据绑定关系调用 maven-compiler-plugin 的 compile 目标。第二种方式是直接在命令行指定要执行的插件目标,例如mvn archetype:generate 就表示调用 maven-archetype-plugin 的 generate 目标,这种带冒号的调用方式与生命周期无关。

认识上述 Maven 插件的基本概念能帮助你理解 Maven 的工作机制,不过要想更高效率地使用 Maven,了解一些常用的插件还是很有必要的,这可以帮助你避免一不小心重新发明轮子。多年来 Maven 社区积累了大量的经验,并随之形成了一个成熟的插件生态圈。Maven 官方有两个插件列表,第一个列表的 GroupId 为 org.apache.maven.plugins,这里的插件最为成熟,具体地址为: http://maven.apache.org/plugins/index.html 。第二个列表的 GroupId 为 org.codehaus.mojo,这里的插件没有那么核心,但也有不少十分有用,其地址为: http://mojo.codehaus.org/plugins.html

接下来笔者根据自己的经验介绍一些最常用的 Maven 插件,在不同的环境下它们各自都有其出色的表现,熟练地使用它们能让你的日常构建工作事半功倍。本文为下半部分。(上半部分内容参见 Maven 实战(七)——常用 Maven 插件介绍(上)

maven-resources-plugin

http://maven.apache.org/plugins/maven-resources-plugin/

为了使项目结构更为清晰,Maven 区别对待 Java 代码文件和资源文件,maven-compiler-plugin 用来编译 Java 代码,maven-resources-plugin 则用来处理资源文件。默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置 maven-resources-plugin 来实现。此外,资源文件过滤也是 Maven 的一大特性,你可以在资源文件中使用 _${propertyName}_ 形式的 Maven 属性,然后配置 maven-resources-plugin 开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者 Profile 传入属性的值,以实现更为灵活的构建。

maven-surefire-plugin

http://maven.apache.org/plugins/maven-surefire-plugin/

可能是由于历史的原因,Maven 2/3 中用于执行测试的插件不是 maven-test-plugin,而是 maven-surefire-plugin。其实大部分时间内,只要你的测试类遵循通用的命令约定(以 Test 结尾、以 TestCase 结尾、或者以 Test 开头),就几乎不用知晓该插件的存在。然而在当你想要跳过测试、排除某些测试类、或者使用一些 TestNG 特性的时候,了解 maven-surefire-plugin 的一些配置选项就很有用了。例如 mvn test -Dtest=FooTest 这样一条命令的效果是仅运行 FooTest 测试类,这是通过控制 maven-surefire-plugin 的 test 参数实现的。

build-helper-maven-plugin

http://mojo.codehaus.org/build-helper-maven-plugin/

Maven 默认只允许指定一个主 Java 代码目录和一个测试 Java 代码目录,虽然这其实是个应当尽量遵守的约定,但偶尔你还是会希望能够指定多个源码目录(例如为了应对遗留项目),build-helper-maven-plugin 的 add-source 目标就是服务于这个目的,通常它被绑定到默认生命周期的 generate-sources 阶段以添加额外的源码目录。需要强调的是,这种做法还是不推荐的,因为它破坏了 Maven 的约定,而且可能会遇到其他严格遵守约定的插件工具无法正确识别额外的源码目录。

build-helper-maven-plugin 的另一个非常有用的目标是 attach-artifact,使用该目标你可以以 classifier 的形式选取部分项目文件生成附属构件,并同时 install 到本地仓库,也可以 deploy 到远程仓库。

exec-maven-plugin

http://mojo.codehaus.org/exec-maven-plugin/

exec-maven-plugin 很好理解,顾名思义,它能让你运行任何本地的系统程序,在某些特定情况下,运行一个 Maven 外部的程序可能就是最简单的问题解决方案,这就是exec:exec的用途,当然,该插件还允许你配置相关的程序运行参数。除了 exec 目标之外,exec-maven-plugin 还提供了一个 java 目标,该目标要求你提供一个 mainClass 参数,然后它能够利用当前项目的依赖作为 classpath,在同一个 JVM 中运行该 mainClass。有时候,为了简单的演示一个命令行 Java 程序,你可以在 POM 中配置好 exec-maven-plugin 的相关运行参数,然后直接在命令运行 mvn exec:java 以查看运行效果。

jetty-maven-plugin

http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

在进行 Web 开发的时候,打开浏览器对应用进行手动的测试几乎是无法避免的,这种测试方法通常就是将项目打包成 war 文件,然后部署到 Web 容器中,再启动容器进行验证,这显然十分耗时。为了帮助开发者节省时间,jetty-maven-plugin 应运而生,它完全兼容 Maven 项目的目录结构,能够周期性地检查源文件,一旦发现变更后自动更新到内置的 Jetty Web 容器中。做一些基本配置后(例如 Web 应用的 contextPath 和自动扫描变更的时间间隔),你只要执行 mvn jetty:run ,然后在 IDE 中修改代码,代码经 IDE 自动编译后产生变更,再由 jetty-maven-plugin 侦测到后更新至 Jetty 容器,这时你就可以直接测试 Web 页面了。需要注意的是,jetty-maven-plugin 并不是宿主于 Apache 或 Codehaus 的官方插件,因此使用的时候需要额外的配置settings.xml的 pluginGroups 元素,将 org.mortbay.jetty 这个 pluginGroup 加入。

versions-maven-plugin

http://mojo.codehaus.org/versions-maven-plugin/

很多 Maven 用户遇到过这样一个问题,当项目包含大量模块的时候,为他们集体更新版本就变成一件烦人的事情,到底有没有自动化工具能帮助完成这件事情呢?(当然你可以使用 sed 之类的文本操作工具,不过不在本文讨论范围)答案是肯定的,versions-maven- plugin 提供了很多目标帮助你管理 Maven 项目的各种版本信息。例如最常用的,命令 mvn versions:set -DnewVersion=1.1-SNAPSHOT 就能帮助你把所有模块的版本更新到 1.1-SNAPSHOT。该插件还提供了其他一些很有用的目标,display-dependency- updates 能告诉你项目依赖有哪些可用的更新;类似的 display-plugin-updates 能告诉你可用的插件更新;然后 use- latest-versions 能自动帮你将所有依赖升级到最新版本。最后,如果你对所做的更改满意,则可以使用 mvn versions:commit 提交,不满意的话也可以使用 mvn versions:revert 进行撤销。

小结

本文介绍了一些最常用的 Maven 插件,这里指的“常用”是指经常需要进行配置的插件,事实上我们用 Maven 的时候很多其它插件也是必须的,例如默认的编译插件 maven-compiler-plugin 和默认的打包插件 maven-jar-plugin,但因为很少需要对它们进行配置,因此不在本文讨论范围。了解常用的 Maven 插件能帮助你事倍功半地完成项目构建任务,反之你就可能会因为经常遇到一些难以解决的问题而感到沮丧。本文介绍的插件基本能覆盖大部分 Maven 用户的日常使用需要,如果你真有非常特殊的需求,自行编写一个 Maven 插件也不是难事,更何况还有这么多开放源代码的插件供你参考。

本文的这个插件列表并不是一个完整列表,读者有兴趣的话也可以去仔细浏览一下 Apache 和 Codehaus Mojo 的 Maven 插件列表,以的到一个更为全面的认识。最后,在线的 Maven 仓库搜索引擎如 http://search.maven.org/ 也能帮助你快速找到自己感兴趣的 Maven 插件。

关于作者

许晓斌(Juven Xu),国内社区公认的 Maven 技术专家、Maven 中文用户组创始人、Maven 技术的先驱和积极推动者,著有《Maven 实战》一书。对Maven 有深刻的认识,实战经验丰富,不仅撰写了大量关于Maven 的技术文章,而且还翻译了开源书籍《Maven 权威指南》,对Maven 技术在国内的普及和发展做出了很大的贡献。就职于Maven 之父的公司,负责维护Maven 中央仓库,是Maven 仓库管理器Nexus(著名开源软件)的核心开发者之一,曾多次受邀到淘宝等大型企业开展Maven 方面的培训。此外,他还是开源技术的积极倡导者和推动者,擅长Java 开发和敏捷开发实践。他的个人网站是: http://www.juvenxu.com

关注 IT 趋势,承载前沿、深入、有温度的内容。感兴趣的读者可以搜索 ID:laocuixiabian,或者扫描下方二维码加关注。

2011 年 5 月 09 日 09:3870876

评论

发布
暂无评论
  • Maven、Ant、Rake:JRuby 1.5 加强配置管理

    随着即将到来的JRuby 1.5版本(预计将在四月底发布),JRuby项目正通过集成Maven、Ant与Rake不断改善Java与Ruby的互操作性。Ruby开发者将能更多地利用Java平台的优势,而Java开发者也将找到更多的理由在已有的项目中使用Ruby工具。

  • 快速构建持续交付系统(三):Jenkins 解决集成打包问题

    通过今天这篇文章,我和你分享了如何快速安装和配置一套有效的Jenkins系统,以及如何打通Jenkins与GitLab之间的访问通道。

    2018 年 9 月 25 日

  • 加餐 | 搭建开发环境、阅读源码方法、经典学习资料大揭秘

    今天,我们来聊点儿不一样的。我总结了3个热度很高的话题,现在一一来为你“揭秘”。

    2019 年 8 月 31 日

  • 我的第一款 Drone 插件

    容器。这些都是可以的。每个开发者都可以使用自己熟悉的语言去开发自己想要的插件。版本的插件开发文档,并开源了一个插件脚手架。

  • 代码贡献者的拦路虎:test::nginx 简介

    测试,是软件开发中必不可少的一个重要环节。

    2019 年 7 月 24 日

  • Maven 开始逃离 XML 阵营

    Maven,这个过去数十来年 Java 应用构建工具的事实标准,已经学会了处理非 XML 写成的构建文件。我们熟知的 polyglot maven,可以通过使用插件来将它的 pom.xml 构建文件的表达方式替换为另一种语言。

  • 第 6 讲 | 从 0 开始整理开发流程

    讲完了第一模块的背景知识,这一节,我来带你整理一下整个游戏开发流程以及流程中所需要的工具。

    2018 年 6 月 7 日

  • Maven 实战(五)——自动化 Web 应用集成测试

    自动化测试这个话题很大,本文不想争论测试先行还是后行,这里强调的是测试的自动化,并基于具体的技术(Maven、JUnit、Jetty等)来介绍一种切实可行的自动化Web应用集成测试方案。当然,自动化测试还包括单元测试、验收测试、性能测试等,在不同的场景下,它们都能为软件开发带来极大的价值。本文仅限于讨论集成测试,主要是因为笔者觉得这是一个非常重要却常常被忽略的实践。

  • Maven 实战(十)——Maven 3,是时候升级了

    去年10月份Apache Maven发布了3.0正式版,而在上个月的22号,Eclipse基金会宣布了Eclipse 3.7(Indigo)的发布,该版本Eclipse最大的新特性之一就是集成了Maven。下载Eclipse IDE for Java Developers版本的用户会发现,Eclipse已经能够自动识别Maven项目了。Indigo中内置的Maven版本是3.0.2,这在一定程度上说明Maven 3已经非常稳定了。不过我相信一定还有很多Maven 2用户在犹豫是否升级,本文会介绍一些Maven 3最重要的特性,旨在帮助读者扫除疑虑,尽早享受Maven 3所能带来的各种便利。

  • OSGi Bundle Convert 插件原理

    普通的web应用要转换为OSGi应用,经常会遇到应用中依赖的Jar是非标准的情况,这些Jar可能只遵守了部分OSGi规范,甚至Manifest信息是空的。这种情况在OSGi 应用中根本无法使用这个非标准的Jar做为Bundle,故必须要将这个非标准的Jar转换成遵守OSGi规范的Bundle。另外用Maven管理的仓库,由于不同开发者对规范的理解不同,在仓库中也存在了各种规范或者不规范的Jar,如果我们能很好的将Maven仓库中的Jar转换成标准的Bundle,Maven仓库也就转换成对应的OSGi Bundle仓库,对于非OSGi的应用而言也就可以很方便的利用Maven仓库,普通web应用也可以平滑的切换到OSGi环境。

  • Maven 实战(二)——POM 重构之增还是删

    无论是对POM内容进行增还是删,其目的都是一样的,就是为了让POM更清晰易懂且让构建更稳定。从这点来说,POM重构与一般的代码重构是类似的。需要谨记的是,重构的前提是完善的自动化测试和持续集成。本文介绍的单个POM规模的重构。

  • 辩论:Maven 是正确的构建工具吗?

    近来,有很多关于Maven的有用性的辩论。Maven是一个基于Java的构建和依赖管理工具,应用在很多项目中。InfoQ深入调查了这个辩论以理解当前的问题是什么以及辩论得出了什么结果

  • 一个好的项目自动化应该是什么样子的?

    今天的基础设施已经让我们的自动化工作变得比以往容易了很多,比如,可执行 JAR 包就比从前部署到应用服务器上简化太多了。

    2019 年 3 月 20 日

  • 在 Flexmojos 中结合使用 Flex 和 Maven – 第 1 部分:初期步骤

    这一系列的文章将介绍Maven的组成,以及如何使用Flexmojos插件管理Flex项目的每个方面,从构建和测试,一直到ASDoc支持和代码范围报告。这是这个3部分系列的第一篇文章。本文将概述Maven和一些术语、Flexmojos,还提供了一个简单的Flex项目供您起步。本系列的第二篇文章将介绍项目设置和自动化、Flash Builder集成、单元测试和多方面项目。最后一篇文章将深入介绍Nexus、RSL、运行时模块、部署和构建版本分析。

  • 当 Ruby 比 Java 构建还快:Buildr

    不喜欢Maven 2.0的人一直在寻找一个XML能更少一些,插件开发能更简易一些的替代方案。Buildr也许是个选择,它的性能甚至比Maven更快。

  • 关于 Java 7 模块系统

    最近,Java模块系统受到了越来越多的关注。原因之一是关于JSR-277和OSGi部分重合的争议。另外就是Java 7的计划。在这篇文章中,Lukas Krecan为我们综合了当前的解决方案,并提出了对即将出现的像Jigsaw和JSR-294这样的方案的担忧。

  • 预习篇 · 从 0 开始搭建 Flutter 工程环境

    今天这篇文章要达到的目的是,帮助你完成Flutter开发测试环境的安装配置。

    2019 年 7 月 1 日

  • Apache Maven JDeps 插件 3.0.0 版本发布

    一个全新的使用jdeps实用程序查找JDK内部API使用情况的maven插件刚刚发布。当该插件被激活时,如果在代码中发现任何对内部API的调用都会导致maven构建失败。从Java 9开始,内部API将变为不可访问,因此这个插件可以帮助开发者让他们的代码与下一版本的Java兼容。尽管标注为3.0.0,实际上这是该插件的第一个发布版本。

发现更多内容

架构师训练营—第九周学习总结

Geek_shu1988

架构师训练营 1 期第 9 周:性能优化(三)- 总结

piercebn

极客大学架构师训练营

架构师训练营第二期 Week 5 作业

bigxiang

极客大学架构师训练营

Week5 作业1

shuyaxx

架构师训练营第 9 周作业

netspecial

极客大学架构师训练营

架构师训练营第 9 周学习总结

netspecial

极客大学架构师训练营

JVM垃圾回收原理,秒杀系统架构方案

garlic

极客大学架构师训练营

【喜讯】Apache DolphinScheduler 荣获 “2020 年度十大开源新锐项目”

海豚调度

Apache DolphinScheduler Apache DolphinScheduler 新一代大数据任务调度 十大开源新锐项目

【架构师训练营第 1 期 09 周】 作业

Bear在挨踢

极客大学架构师训练营

架构师训练营 week9 作业

陈皓07

Java 中常见的细粒度锁实现

rookiedev

Java 多线程 细粒度锁

架构师训练营第5周总结

Sandman

极客大学架构师训练营

我的亲历:一行代码,百万人民币打水漂

白色蜗牛

Java 程序员 架构 程序人生 职场

架构师训练营 week5 课后作业

花果山

极客大学架构师训练营

秒杀系统

橘子皮嚼着不脆

第五周总结

孤星

架构师训练营—第九周作业

Geek_shu1988

【架构师训练营第 1 期 09 周】 学习总结

Bear在挨踢

极客大学架构师训练营

架构师训练营 week5 学习总结

花果山

极客大学架构师训练营

5G+工业互联网的中国登山队,如何攀跃“产业化”山峦?

脑极体

架构师训练营 - 第九周作业

一个节点

极客大学架构师训练营

架构师训练营 - 第九周总结

一个节点

极客大学架构师训练营

架构师训练营第九周课程笔记及心得

Airs

【架构师训练营】第九周作业:性能优化

MindController

秒杀系统

架构师训练营第 9 周课后练习

叶纪想

极客大学架构师训练营

架构训练营第五周作业

一期一会

极客大学架构师训练营第五周作业

井中人

极客大学架构师训练营

二分法求平方根,swift面向协议编程protocol从入门到精通、《格局》吴军著读后感、John 易筋 ARTS 打卡 Week 27

John(易筋)

collection ARTS 打卡计划 格局 吴军 李嘉图定律 面向协议protocol编程

一次用户故事拆(SPIDR)法实践

Bruce Talk

Agile 用户故事 User Story

技术选型总结一

Mars

技术选型

架构师训练营第二期 Week 5 总结

bigxiang

极客大学架构师训练营

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

Maven实战(八)——常用Maven插件介绍(下)-InfoQ