Archive

Posts Tagged ‘Maven’

持续交付离我们有多远

November 18th, 2013 No comments

上周我在2013苏州软件开发者大会发表题为‘持续交付离我们有多远’演讲,主要介绍了我实际工作中的一个案例,并辅以归纳思考和总结,以下是Slides。


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2013/11/18/how-far-is-continuous-delivery-away-from-us/

普适的依赖倒置原则

July 5th, 2013 No comments

近日与@linux_china聊天后所感。

OO设计内的依赖倒置原则

OO设计有个著名的依赖倒置原则(Dependency Inversion Principle, DIP),提出者是Robert C. Martin,这一原则在他著作《敏捷软件开发——原则、模式与实践》中有详细论述,先简单复习下。

例如我们有一个Button类和一个Lamp类,按钮(Button)控制灯(Lamp)的开和关:

这是非常直观的做法,即让Button依赖Lamp,因为毕竟它要操作Lamp嘛。这么做的问题在于,当Lamp的变化很容易影响到Button,而且鉴于这种强依赖的存在,Button和Lamp的界限不是很清晰。这让测试也变得麻烦,想象下如果Lamp是个非常复杂的对象,那当我测试Button的时候就必须准备好Lamp,完全没必要嘛。

解决上述的问题就是加一层,Robert C. Martin书中的例子就是给加上一个ButtonServer的接口,该接口定义了turnOn和turnOff方法,而Button现在依赖于ButtonServer。那现在Button是干净了,它完全不知道Lamp的存在,一切操作基于接口了,界限明晰且测试方便。Lamp现在实现了ButtonServer,如果你把Button和ButtonServer看成一伙的,那很显然现在依赖的方向反过来了,原来是Button向下依赖Lamp,现在变成了Lamp向上依赖ButtonServer,这就是为什么我们称其为依赖倒置

OO设计外的依赖倒置原则

前面啰啰嗦嗦一堆其实就是铺垫,炒冷饭毕竟没太大意思,本文的重点是把这个原则展开来想想,而不要限制在面向对象的世界里。比如说Maven的依赖管理,在Maven之前,依赖管理是命令式的,即如果我要用某个依赖如log4j的时候,我得准备jar文件及相关目录,编译的时候指定classpath。这里我的项目的的确确需要log4j,实现的方式差不多就类似于上面的Button直接依赖Lamp。

声明式就不一样了,我的项目需要log4j,我这么写:

这段东西其实就是一个接口,相当于上面的ButtonService。其实对于我的项目来说,我就关心要一个log4j,能让我编译、测试、打包都OK,我根本不关心这玩意儿从哪里来,放哪里,正确与否最好也最好由别人帮我考虑好。嗯,这正是Maven干的事情。

这时候,与其用依赖倒置的思路来考虑这个问题,还不如说这些事情都是基于一个约定、或者基于一个协议。ButtonService是一个协议,POM的依赖声明是一个协议,有了协议,上层就不用关心那么多细枝末节了。

我们再跳到另外一块地方看看依赖倒置,我们看看环境管理。例如我要部署一个Java应用,我要关心的环境有:JVM、Apache/Nginx、JBoss/Jetty、MySql…… OK,直接的做法显然是一个个安装,哪里下载、装在哪里、如何配置,都可以写点shell做自动化。嗯,这里我的应用是Button,环境是Button,这个依赖还是从上往下的。

怎么反过来?当然我们得首先定义个接口,或者约定,或者协议,这样我的应用只关心接口就可以了,这样的接口可以是:

是的,这是Puppet,在比较理想的情况下,对应用来说我只需要说,我要哪些基础软件服务,我根本不关心也不想关心他们怎么安装、配置、管理、升级,这些事情,让Puppet/Chef去管吧!

你说依赖反转也好,说基于协议也好,说基于约定也好,说声明式优于命令式也好,都差不多是这个意思。


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2013/07/05/universal-dip/

Categories: 软件设计 Tags: , , ,

May your builds always succeeds!

October 6th, 2011 2 comments

Just finished the book “Building and Testing with Gradle” in this vacation, and here is my review.

First of all this book has a great Foreword by Ken Sipe, the CTO of Gradleware. I totally agree with him on

What I have discovered over the years as a software engineer is that in order to solve a problem best, I have to understand the model. The reason make wasn’t a great build tool for Java is that it didn’t have a way to express the model well. Ant gave us platform independence and a better vocabulary, but a weak model. Maven provided a stronger model, which is why so many people prefer it over Ant. The challenge for Maven is that it provided a “the one model to rule them all”. You’re able to express your build needs within that model and only that model.

Gradle fills the gap. Gradle provides a way of modeling a build system using a DSL with convention over configuration, yet allowing an enterprise to define its own model. It goes deeper than this, as explained in this introductory book by Matthew and Tim, but modeling by convention is truly a game changer for enterprise software development.

To simplify, Make has no build model, Ant has weak model, Maven has one (and only one) strong model, and Gradle allows you do define model. I’m not saying Gradle is better than Maven, actually I think in most cases, one strong model is better than allowing people define models. But the ‘model’ concept is the key to undertand the differences among those tools.

BTW, the title of this post if borrowed from Ken’s foreword :).

This is one of the shortest technique book I’ve ever read, only 110 pages composed by 6 chapters:

  1. Hello, Gradle!
  2. Gradle Tasks
  3. Ant and Gradle
  4. Maven and Gradle
  5. Testing with Gradle
  6. Multiproject Builds

Just like any tool introduction book, the first chapter is for the very beginners. The ‘Gradle Tasks’ chapter is the most valuable part of this book, it does a good job explaining this key concept, and in a practical way. The third chapter is for Ant users the fourth is for Maven users, I belong to the latter. From the ‘Maven and Gradle’ chapter I can see the Gradle implementations of Maven concepts like coordinate, dependency, repository, and convention, but a bit disappointed on the missing of lifecycle. The ‘Testing with Gradle’ has little value, it’s just too basic. The last chapter is on multi-project builds, or sometimes we call this multi-module builds. Any real project is multi-moduled so I could not skip it. This chapters introduces 3 ways to organize your modules, one build file for each module, one master build file for all modules, and in a hybrid way which some modules have build file while somes don’t. This is interesting to me because Maven only gives me one choice. But, when I looked forward to see some advice on when to use which style, the authors told me to decide by myself :(.

Too short the book is so sometimes I have to refer to the official gradle user guide to understand something. The authors mentioned that there will be future volumes for Gradle plugin ecosystem and Java plugin, besides, I also hope there will be something on Gradle’s lifecycle, and more importantly, real world examples and best practices. This is the only published Gradle book and Gradle itself is only on version 1.0-milestone-3, so there is a lot of space to improve.

Thanks to Tim Berglund & Matthew McCullough for making this book out.


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2011/10/06/may-your-builds-always-succeeds/

Categories: Tags: , , , ,

InfoQ Maven专栏(十)——Maven 3,是时候升级了

August 5th, 2011 12 comments

去年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所能带来的各种便利。

确保兼容性

在升级软件的时候,兼容性显然是首先要考虑的问题,如果原本在Maven 2下能成功构建的项目,在Maven 3下立刻就失败了,而且难以简单修复,那显然是不可接受的。 好在Maven用户大可打消这一顾虑,Maven 3自设计之初就一直考虑与Maven 2的兼容性,这不仅是指兼容Maven 2的核心,还包括大量的org.apache.maven.plugins与org.codehaus.mojo插件。虽然由于某些插件代码的特殊性,无 法做到100%完全的兼容,但已经基本不会遇到问题了。

如果你还有担心,那可以先仔细阅读官方发布的Maven 3.x兼容性笔记Maven 3.x插件兼容性列表。这两份文档记录的兼容性问题主要涉及的是一些应当被弃用的特性,并且都给出了Maven 3下的解决方案。

改进性能

Maven 3的性能较之于Maven 2是有了很大的进步的,这体现在内存占用的减少和构建时间的减少两个方面。特别是Maven 3引入的并行构建特性,能够分析项目模块之间的依赖关系,然后并行地构建那些相互间没有依赖关系的模块,从而充分利用如今普遍的多核CPU资源。

以下两条命令分别表示用4个线程构建,以及根据CPU核数每个核分配1个线程进行构建:

Maven的提交者之一Anders Hammar在其文章迁移到Maven 3的十大理由中介绍了一个简单的实验,分别用Maven 2.2.1,Maven 3.0.2(单线程),和Maven 3.0.2(4线程)构建同样的包含32个模块的Maven源代码,得到了如下的结果:

Table 1. 用”mvn package”构建Maven SCM trunk(32个模块)
时间/内存
Maven 2.2.1 3:20/53M
Maven 3.0.2(单线程) 3:15/27M
Maven 3.0.2(4线程) 2:26/28M

可以看到Maven 3下内存的占用减少了近一半!而开启并行构建后,时间的节省也是非常可观的。而项目越大,这种性能的改进就越为明显。如果你的开发环境没有充裕的内存,而你的项目又非常大,那光内存节省这一条就足以让你立刻转向Maven 3了。

改进模块间依赖解析

Maven 2中一个比较令人头疼的问题是,当你在构建一个多模块项目的时候,为了使前面的模块能在后面模块classpath中生效,你必须将其install到本 地仓库中之后,Maven才能解析使用。几乎所有Maven 2用户或早或晚都遇到了这个困惑,“为什么我已经 mvn clean package 了模块A,可构建模块B的时候还是无法看到A的更新呢?”这个问题在Maven 3中得以解决了,在构建多模块项目的时候,Maven 3会从反应堆(reactor)中解析模块间依赖,也就是说只要模块A执行了package,那模块B就能根据相对路径找到并解析使用A生成的jar文 件。

提倡最佳实践

刚从Maven 2转到Maven 3的用户很可能会发现执行构建的时候命令行会打印很多如下的警告:

大部分如下的警告是因为用户在配置插件或者依赖的时候没有指定版本,无法保证构建的可重现性,从而为构建引入了潜在的风险。这样的警告是一种既保持兼容性,又提倡最佳实践而做出的权衡。类似的改进还包括弃用profile.xml特性、明确分离项目依赖和插件依赖等等。

改进日志输出

这是一个很微小的改进,却突显了Maven开发者对Maven用户的关怀,我个人非常喜欢这点改进。简单得来说,Maven 3的构建日志更容易阅读了。插件的输出之间都有空行隔开,每个被运行插件的版本、目标、以及所处模块的artifactId都得以清晰显示。当构建出现错 误的时候,这样的输出能帮助用户更快地找到问题所在。

站点(注意!)

站点这一特性是Maven 2的核心,但是在Maven 3中,该特性被完全移到了maven-site-plugin中,这就导致了相关的配置也需要转移。Maven 2中与站点相关的配置是在POM的reporting元素下的,如:

在Maven 3中,所有站点相关的配置都应该出现在maven-site-plugin下面:

小结与致谢

本文从兼容性、新特性、性能改进、以及重要细节等方面全面介绍了Maven 3。Maven 3是Maven从成熟走向巅峰的标志,如果你还未升级,我强烈建议你至少尝试一下,Maven的安装是非常简单的,只需要下载一个zip包、解压、然后设置简单的环境变量即可,马上去下载吧

由于能力及精力所限,我已经很难再写更多既不重复又符合很多读者口味的Maven文章,因此暂且计划将该专栏告一段落。我衷心感谢张凯峰的策划和编 辑,感谢读者的支持,另外也感谢我的家人,特别是我三岁的女儿,那些给写稿的时间本该属于她们。最后,我还是会持续关心 Maven的发展,有机会也一定会分享更多的经验和心得。

本文已经首发于InfoQ中文站,版权所有,原文为《Maven实战( 十)——Maven 3,是时候升级了》如需转载,请务必附带本声明,谢谢。
InfoQ中文站是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如架构师》等。


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2011/08/05/infoq-maven-time-to-upgrade-to-maven3/

Categories: Maven Tags: , , ,

InfoQ Maven专栏(九)——打包的技巧

August 5th, 2011 3 comments

“打包“这个词听起来比较土,比较正式的说法应该是”构建项目软件包“,具体说就是将项目中的各种文件,比如源代码、编译生成的字节码、配置文件、文档,按照规范的格式生成归档,最常见的当然就是JAR包和WAR包了,复杂点的例子是Maven官方下载页面的分发包, 它有自定义的格式,方便用户直接解压后就在命令行使用。作为一款”打包工具“,Maven自然有义务帮助用户创建各种各样的包,规范的JAR包和WAR包 自然不再话下,略微复杂的自定义打包格式也必须支持,本文就介绍一些常用的打包案例以及相关的实现方式,除了前面提到的一些包以外,你还能看到如何生成源 码包、Javadoc包、以及从命令行可直接运行的CLI包。

Packaging的含义

任何一个Maven项目都需要定义POM元素packaging(如果不写则默认值为jar)。顾名思义,该元素决定了项目的打包方式。实际的情形 中,如果你不声明该元素,Maven会帮你生成一个JAR包;如果你定义该元素的值为war,那你会得到一个WAR包;如果定义其值为POM(比如是一个 父模块),那什么包都不会生成。除此之外,Maven默认还支持一些其他的流行打包格式,例如ejb3和ear。你不需要了解具体的打包细节,你所需要做 的就是告诉Maven,”我是个什么类型的项目“,这就是约定优于配置的力量。

为了更好的理解Maven的默认打包方式,我们不妨来看看简单的声明背后发生了什么,对一个jar项目执行mvn package操作,会看到如下的输出:

相比之下,对一个war项目执行mvn package操作,输出是这样的:

对应于同样的package生命周期阶段,Maven为jar项目调用了maven-jar-plugin,为war项目调用了maven-war-plugin,换言之,packaging直接影响Maven的构建生命周期。了解这一点非常重要,特别是当你需要自定义打包行为的时候,你就必须知道去配置哪个插件。一个常见的例子就是在打包war项目的时候排除某些web资源文件,这时就应该配置maven-war-plugin如下:

源码包和Javadoc包

本专栏的《坐标规划》一 文中曾解释过,一个Maven项目只生成一个主构件,当需要生成其他附属构件的时候,就需要用上classifier。源码包和Javadoc包就是附属 构件的极佳例子。它们有着广泛的用途,尤其是源码包,当你使用一个第三方依赖的时候,有时候会希望在IDE中直接进入该依赖的源码查看其实现的细节,如果 该依赖将源码包发布到了Maven仓库,那么像Eclipse就能通过m2eclipse插件解析下载源码包并关联到你的项目中,十分方便。由于生成源码 包是极其常见的需求,因此Maven官方提供了一个插件来帮助用户完成这个任务:

类似的,生成Javadoc包只需要配置插件如下:

为了帮助所有Maven用户更方便的使用Maven中央库中海量的资源,中央仓库的维护者强制要求开源项目提交构件的时候同时提供源码包和Javadoc包。这是个很好的实践,读者也可以尝试在自己所处的公司内部实行,以促进不同项目之间的交流。

可执行CLI包

除了前面提到了常规JAR包、WAR包,源码包和Javadoc包,另一种常被用到的包是在命令行可直接运行的CLI(Command Line)包。默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件,而要得到一个可以直接在命令行通过java命令运行的 JAR文件,还要满足两个条件:

  • JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。
  • 项目所有的依赖都必须在Classpath中。

Maven有好几个插件能帮助用户完成上述任务,不过用起来最方便的还是maven-shade-plugin, 它可以让用户配置Main-Class的值,然后在打包的时候将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖,它很聪明地将依 赖JAR文件全部解压后,再将得到的.class文件连同当前项目的.class文件一起合并到最终的CLI包中,这样,在执行CLI JAR文件的时候,所有需要的类就都在Classpath中了。下面是一个配置样例:

上述例子中的,我的Main-Class是com.juvenxu.mavenbook.HelloWorldCli,构建完成后,对应于一个常规 的hello-world-1.0.jar文件,我还得到了一个hello-world-1.0-cli.jar文件。细心的读者可能已经注意到了,这里 用的是cli这个classifier。最后,我可以通过java -jar hello-world-1.0-cli.jar命令运行程序。

自定义格式包

实际的软件项目常常会有更复杂的打包需求,例如我们可能需要为客户提供一份产品的分发包,这个包不仅仅包含项目的字节码文件,还得包含依赖以及相关脚本文件以方便客户解压后就能运行,此外分发包还得包含一些必要的文档。这时项目的源码目录结构大致是这样的:

除了基本的pom.xml和一般Maven目录之外,这里还有一个src/main/scripts/目录,该目录会包含一些脚本文件如 run.sh和run.bat,src/main/assembly/会包含一个assembly.xml,这是打包的描述文件,稍后介绍,最后的 README.txt是份简单的文档。

我们希望最终生成一个zip格式的分发包,它包含如下的一个结构:

其中bin/目录包含了可执行脚本run.sh和run.bat,lib/目录包含了项目JAR包和所有依赖JAR,README.txt就是前面提到的文档。

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

  • 首先这个assembly.xml文件的id对应了其最终生成文件的classifier。
  • 其次formats定义打包生成的文件格式,这里是zip。因此结合id我们会得到一个名为hello-world-1.0-bin.zip的文件。(假设artifactId为hello-world,version为1.0)
  • dependencySets用来定义选择依赖并定义最终打包到什么目录,这里我们声明的一个depenencySet默认包含所有所有 依赖,而useProjectArtifact表示将项目本身生成的构件也包含在内,最终打包至输出包内的lib路径下(由 outputDirectory指定)。
  • fileSets允许用户通过文件或目录的粒度来控制打包。这里的第一个fileSet打包README.txt文件至包的根目录下,第二个fileSet则将src/main/scripts下的run.sh和run.bat文件打包至输出包的bin目录下。

打包描述文件所支持的配置远超出本文所能覆盖的范围,为了避免读者被过多细节扰乱思维,这里不再展开,读者若有需要可以去参考这份文档

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

运行mvn clean package之后,我们就能在target/目录下得到名为hello-world-1.0-bin.zip的分发包了。

小结

打包是项目构建最重要的组成部分之一,本文介绍了主流Maven打包技巧,包括默认打包方式的原理、如何制作源码包和Javadoc包、如何制作命 令行可运行的CLI包、以及进一步的,如何基于个性化需求自定义打包格式。这其中涉及了很多的Maven插件,当然最重要,也是最为复杂和强大的打包插件 就是maven-assembly-plugin。事实上Maven本身的分发包就是通过maven-assembly-plugin制作的,感兴趣的读 者可以直接查看源码一窥究竟。

本文已经首发于InfoQ中文站,版权所有,原文为《Maven实战(九)——打包的技巧》如需转载,请务必附带本声明,谢谢。
InfoQ中文站是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如架构师》等。


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2011/08/05/infoq-maven-packag/

InfoQ Maven专栏(八)——常用Maven插件介绍(下)

May 11th, 2011 3 comments

我们都知道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插件,在不同的环境下它们各自都有其出色的表现,熟练地使用它们能让你的日常构建工作事半功倍。本文为下半部分。(上半部分内容参见InfoQ 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插件。

本文已经首发于InfoQ中文站,版权所有,原文为《Maven实战(八)——常用Maven插件介绍(下)》如需转载,请务必附带本声明,谢谢。
InfoQ中文站是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如架构师》等。


原创文章,转载请注明出处, 本文地址: http://www.juvenxu.com/2011/05/11/infoq-maven-most-used-maven-plugins-b/