<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Juven Xu</title>
	<atom:link href="http://www.juvenxu.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.juvenxu.com</link>
	<description>Maven, 开源, Java, 敏捷</description>
	<lastBuildDate>Sun, 05 Feb 2012 04:57:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Addison-Wesley的大师签名系列图书</title>
		<link>http://www.juvenxu.com/2012/02/05/addison-wesley-signature-series/</link>
		<comments>http://www.juvenxu.com/2012/02/05/addison-wesley-signature-series/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 04:57:01 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[书]]></category>
		<category><![CDATA[Addison-Wesley]]></category>
		<category><![CDATA[敏捷]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=661</guid>
		<description><![CDATA[在‘阅读计算机图书的一些心得’中我提过 首先是挑书，我在读书的同时慢慢锻炼了挑书的能力，因为读书最大的消费不是书价，而是时间，因此挑对书是至关重要的。我读书主要是看出版社，比如国外著名的有O’Reilly、Manning、Addison Wesley、Pragmatic Bookshelf等等，这些出版社的书大部分质量非常优秀，也包含了不少的经典，就算你不小心遇到本很水的，那几率也是非常地低。 本文就介绍一个我认为质量非常非常之高的系列图书（注意，是两个非常哦），它就是Addison-Wesley的大师签名系列，具体的它是三个子系列，签名者分别为： Martin Fowler：http://www.informit.com/imprint/series_detail.aspx?ser=2629220 Mike Cohn：http://www.informit.com/imprint/series_detail.aspx?ser=2393388 Kent Beck：http://www.informit.com/imprint/series_detail.aspx?ser=2175138 这其中Martin Fowler相信大家已经耳熟能详了，包括他的《重构》和他所在的ThoughtWorks，为软件行业做了很大的贡献。Kent Beck的知名更多的是因为他在极限编程和TDD方面的贡献。而Mike Cohn则是敏捷流程方面的专家，Scrum联盟的创立者之一。 那么这三个系列中到底有什么好书呢？名气大的一大把，最近很热的《持续交付》，Kent Beck的著作《测试驱动开发》，前几年得过Jolt Award的《持续集成》，Martin自己的《企业应用架构模式》等等。 挑书的时候，名气当然是一个重要考虑的因素的，以我自己为例，当《持续交付》英文版刚出来的时候，我只是觉得是本好书，并没有立即去读的欲望，但随着越来越多的人推崇这本书，我就觉得需要快点拿来一读了，这就是名气的影响。 但名气只是一个因素而已，这个大师签名系列中，就我读过的而言，好几本其实在国内没什么名气，但确实是难得的好书，我特别推崇的有： Growing Object-Oriented Software, Guided by Tests：初看起来是本讲TDD的书，但本书充满了OO设计的智慧，而且案例非常实在。 Agile Testing: A Practical Guide for Testers and Agile Teams：敏捷开发的流程中，测试到底是个怎样的角色？我们应该怎么样去做测试，这不仅仅是每个测试人员要考虑，作为程序员，也应该认真关心。 该系列的图书，封面设计也作得很漂亮，风格一致，色彩也很不沉闷，如果你细心观察，会注意到Martin签名系列的封面上都是一座桥。然后可惜的是，这些图书一经引进，风格再难保持一致，有些是翻译有些是影印，出版社也各不相同，这些都是客观因素。 这个签名系列图书中大部分已经由国内出版社翻译引进了，有几本是影印，有兴趣的可以上豆瓣搜索对应版本，所以阅读渠道还是挺畅通的，英文好的也可以直接购买电子版，英文好再加上舍得花钱的，可直接上amazon.com购买纸质版。]]></description>
			<content:encoded><![CDATA[<p>在‘<a href="http://www.juvenxu.com/2011/10/25/what-i-learned-on-reading-it-books/">阅读计算机图书的一些心得</a>’中我提过</p>
<blockquote><p>首先是挑书，我在读书的同时慢慢锻炼了挑书的能力，因为读书最大的消费不是书价，而是时间，因此挑对书是至关重要的。我读书主要是看出版社，比如国外著名的有O’Reilly、Manning、Addison Wesley、Pragmatic Bookshelf等等，这些出版社的书大部分质量非常优秀，也包含了不少的经典，就算你不小心遇到本很水的，那几率也是非常地低。</p></blockquote>
<p>本文就介绍一个我认为质量非常非常之高的系列图书（注意，是两个非常哦），它就是Addison-Wesley的大师签名系列，具体的它是三个子系列，签名者分别为：</p>
<ul>
<li>Martin Fowler：<a href="http://www.informit.com/imprint/series_detail.aspx?ser=2629220">http://www.informit.com/imprint/series_detail.aspx?ser=2629220</a></li>
<li>Mike Cohn：<a href="http://www.informit.com/imprint/series_detail.aspx?ser=2393388">http://www.informit.com/imprint/series_detail.aspx?ser=2393388</a></li>
<li>Kent Beck：<a href="http://www.informit.com/imprint/series_detail.aspx?ser=2175138">http://www.informit.com/imprint/series_detail.aspx?ser=2175138</a></li>
</ul>
<p><img class="size-medium wp-image-666 alignright" title="kent_beck" src="http://www.juvenxu.com/wp-content/uploads/2012/02/kent_beck-198x300.jpg" alt="" width="130" height="200" /><img class="size-full wp-image-664 alignright" title="Martin Fowler" src="http://www.juvenxu.com/wp-content/uploads/2012/02/martin_fowler.jpg" alt="" width="150" height="200" /></p>
<p>这其中Martin Fowler相信大家已经耳熟能详了，包括他的《重构》和他所在的ThoughtWorks，为软件行业做了很大的贡献。Kent Beck的知名更多的是因为他在极限编程和TDD方面的贡献。而Mike Cohn则是敏捷流程方面的专家，Scrum联盟的创立者之一。</p>
<p>那么这三个系列中到底有什么好书呢？名气大的一大把，最近很热的《持续交付》，Kent Beck的著作《测试驱动开发》，前几年得过Jolt Award的《持续集成》，Martin自己的《企业应用架构模式》等等。</p>
<p>挑书的时候，名气当然是一个重要考虑的因素的，以我自己为例，当《持续交付》英文版刚出来的时候，我只是觉得是本好书，并没有立即去读的欲望，但随着越来越多的人推崇这本书，我就觉得需要快点拿来一读了，这就是名气的影响。</p>
<p>但名气只是一个因素而已，这个大师签名系列中，就我读过的而言，好几本其实在国内没什么名气，但确实是难得的好书，我特别推崇的有：</p>
<ul>
<li>Growing Object-Oriented Software, Guided by Tests：初看起来是本讲TDD的书，但本书充满了OO设计的智慧，而且案例非常实在。</li>
<li>Agile Testing: A Practical Guide for Testers and Agile Teams：敏捷开发的流程中，测试到底是个怎样的角色？我们应该怎么样去做测试，这不仅仅是每个测试人员要考虑，作为程序员，也应该认真关心。</li>
</ul>
<p><a href="http://www.juvenxu.com/wp-content/uploads/2012/02/cd.jpeg"><img class="size-full wp-image-674 alignnone" style="margin-left: 10px; margin-right: 2px;" title="cd" src="http://www.juvenxu.com/wp-content/uploads/2012/02/cd.jpeg" alt="" width="120" height="160" /></a><a href="http://www.juvenxu.com/wp-content/uploads/2012/02/at.jpeg"><img class="size-full wp-image-675 alignnone" style="margin-left: 2px; margin-right: 2px;" title="at" src="http://www.juvenxu.com/wp-content/uploads/2012/02/at.jpeg" alt="" width="120" height="160" /></a><a href="http://www.juvenxu.com/wp-content/uploads/2012/02/go.jpeg"><img class="size-full wp-image-676 alignnone" style="margin-left: 2px; margin-right: 2px;" title="go" src="http://www.juvenxu.com/wp-content/uploads/2012/02/go.jpeg" alt="" width="120" height="160" /></a><a href="http://www.juvenxu.com/wp-content/uploads/2012/02/tdd.jpeg"><img class="size-full wp-image-677 alignnone" style="margin-left: 2px; margin-right: 2px;" title="tdd" src="http://www.juvenxu.com/wp-content/uploads/2012/02/tdd.jpeg" alt="" width="120" height="160" /></a></p>
<p>该系列的图书，封面设计也作得很漂亮，风格一致，色彩也很不沉闷，如果你细心观察，会注意到Martin签名系列的封面上都是一座桥。然后可惜的是，这些图书一经引进，风格再难保持一致，有些是翻译有些是影印，出版社也各不相同，这些都是客观因素。</p>
<p>这个签名系列图书中大部分已经由国内出版社翻译引进了，有几本是影印，有兴趣的可以上豆瓣搜索对应版本，所以阅读渠道还是挺畅通的，英文好的也可以直接购买电子版，英文好再加上舍得花钱的，可直接上amazon.com购买纸质版。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2012/02/05/addison-wesley-signature-series/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>培育软件的可测试性</title>
		<link>http://www.juvenxu.com/2011/12/27/cultivate-software-testability/</link>
		<comments>http://www.juvenxu.com/2011/12/27/cultivate-software-testability/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 07:15:22 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[敏捷]]></category>
		<category><![CDATA[可测试性]]></category>
		<category><![CDATA[演讲]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=654</guid>
		<description><![CDATA[本月我在AgileTour上发表了一个演讲，主题为‘培育软件的可测试性’，该主题讲述了三个问题： 为什么要关注软件的可测试性？ 什么是软件的可测试性？ 如何提高软件的可测试性？ 培育软件的可测试性 View more presentations from agiletourchina]]></description>
			<content:encoded><![CDATA[<p>本月我在<a href="http://agiletour.cn/">AgileTour</a>上发表了一个演讲，主题为‘培育软件的可测试性’，该主题讲述了三个问题：</p>
<ul>
<li>为什么要关注软件的可测试性？</li>
<li>什么是软件的可测试性？</li>
<li>如何提高软件的可测试性？</li>
</ul>
<div style="width:510px" id="__ss_10671115"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/agiletourchina/ss-10671115" title="培育软件的可测试性" target="_blank">培育软件的可测试性</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10671115" width="510" height="426" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/agiletourchina" target="_blank">agiletourchina</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/12/27/cultivate-software-testability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>没有银弹，但你也需要子弹——读《测试驱动开发的艺术》</title>
		<link>http://www.juvenxu.com/2011/11/07/review-on-lasse-koskela-s-tdd-book/</link>
		<comments>http://www.juvenxu.com/2011/11/07/review-on-lasse-koskela-s-tdd-book/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 09:02:41 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[书]]></category>
		<category><![CDATA[敏捷]]></category>
		<category><![CDATA[ATDD]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[书评]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=642</guid>
		<description><![CDATA[昨晚我发了条微博，内容如下： 编程本质上是用脑的，当程序复杂的时候人脑会不够用，于是bug百出，程序员心力憔悴。好在出现了各种工具和方法论来帮助降低人脑的负荷，让人能够专注于有限的地方。但是，很多人迷信工具和方法论以致几乎忽略了人脑的能力，就好像只要用对了方法和工具，放只猴子也能把软件写出来，这也应该反思。 这是我最近看到一些关于敏捷方法的争论有感而发，就以测试驱动开发（TDD）为例，有那么两派人，一派是死忠，认为不用TDD写不出好的代码，不写测试就不能写主代码；另一派则相反，觉得TDD是很扯淡的东西，是咨询公司忽悠人的工具。我则认为两派都走了极端，在我看来，包括TDD在内的敏捷方法论都旨在帮助降低程序员的脑负荷，因此恰当的使用能帮助我们专注于重要的事情，但认为TDD是万能的，而忽视了人，那也大错特错了，不管多么神奇的方法，多么完善的过程，我们都不能否认人脑思考是编程活动中最重要的一环。 所以TDD不是能让你秒杀狼人的银弹，但它的确是能帮助打猎的子弹。 回到《测试驱动开发的艺术》一书上来，首先我想批评的是这个看似很雅实则恶俗的题目，原书名为 Test Driven &#8211; Practical TDD and Acceptance TDD for Java Developers ，一经翻译，意思完全走样。这书比较重在介绍TDD（包括ATDD）以及相关的实践，离”艺术”二字真差十万八千里。不过除了题目，其他一切都不错，包括那个照搬的Manning系列封面。下面介绍下内容： 第1-3章 是对TDD入门的介绍，TDD是什么，为什么要用TDD，相关工具，然后是实际操作等等。由于TDD无法脱离重构而存在，因此这里也有不少涉及。这一部分很棒，不是说内容多精彩，重要的是浅显易懂。 第4章 是对TDD概念和模式的一些挖掘，也是期望比较大的一章，我也看到了一些精彩的论述，包括如何提高代码可测试性的手段，将测试分为基于状态和基于交互两类，等等。可惜不够过瘾，作者引申的书倒不少，自己的料不够足啊。 第5-8章 就是一些实际的实践了，可能也算本书的重头，包括测试web组件，数据访问组件，Swing组件，时间相关功能，以及多线程代码等等。根据自己背景需要，跳着看看就可以了。 第9-11章 是对验收测试驱动开发（ATDD）的介绍，是我个人，除第4章之外最喜欢的部分，因为我之前对TDD了解得不算少了，但对验收测试的了解寥寥，这部分帮助我扫盲了，也学习了一下相关工具Fit（由Wiki之父Ward Cunningham开发）。 第12章 也是最后一章，是教你如何推行TDD，基本上是一些咨询培训的技巧，也挺有趣，不过故事少了点（作者自己还在文中强调故事的重要性，有点搞笑啊）。 总得来说这是本介绍TDD和ATDD的不错的书，优点在于浅显易懂，而且有不少实践，缺点就是深度不够。 和TDD相关的书还有不少，顺带介绍几本不错的： Test Driven Development by Kent Beck 极限编程之父的经典，必读 Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce 我个人非常非常喜欢的一本书，他告诉了TDD就是面向对象设计，启发非常之大 Agile Testing by Lisa Crispin and Janet [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.juvenxu.com/wp-content/uploads/2011/11/tdd-book.jpg"><img class="alignright size-medium wp-image-645" title="tdd-book" src="http://www.juvenxu.com/wp-content/uploads/2011/11/tdd-book-300x300.jpg" alt="" width="300" height="300" /></a>昨晚我发了条<a href="http://weibo.com/1671981772/xtO9dfE4w" target="_blank">微博</a>，内容如下：</p>
<blockquote><p>编程本质上是用脑的，当程序复杂的时候人脑会不够用，于是bug百出，程序员心力憔悴。好在出现了各种工具和方法论来帮助降低人脑的负荷，让人能够专注于有限的地方。但是，很多人迷信工具和方法论以致几乎忽略了人脑的能力，就好像只要用对了方法和工具，放只猴子也能把软件写出来，这也应该反思。</p></blockquote>
<p>这是我最近看到一些关于敏捷方法的争论有感而发，就以测试驱动开发（TDD）为例，有那么两派人，一派是死忠，认为不用TDD写不出好的代码，不写测试就不能写主代码；另一派则相反，觉得TDD是很扯淡的东西，是咨询公司忽悠人的工具。我则认为两派都走了极端，在我看来，包括TDD在内的敏捷方法论都旨在帮助降低程序员的脑负荷，因此恰当的使用能帮助我们专注于重要的事情，但认为TDD是万能的，而忽视了<strong>人</strong>，那也大错特错了，不管多么神奇的方法，多么完善的过程，我们都不能否认人脑思考是编程活动中最重要的一环。</p>
<p>所以TDD不是能让你秒杀狼人的<a href="http://en.wikipedia.org/wiki/Silver_bullet" target="_blank">银弹</a>，但它的确是能帮助打猎的子弹。</p>
<p>回到《测试驱动开发的艺术》一书上来，首先我想批评的是这个看似很雅实则恶俗的题目，原书名为 Test Driven &#8211; Practical TDD and Acceptance TDD for Java Developers ，一经翻译，意思完全走样。这书比较重在介绍TDD（包括ATDD）以及相关的实践，离”艺术”二字真差十万八千里。不过除了题目，其他一切都不错，包括那个照搬的Manning系列封面。下面介绍下内容：</p>
<ul>
<li>第1-3章 是对TDD入门的介绍，TDD是什么，为什么要用TDD，相关工具，然后是实际操作等等。由于TDD无法脱离重构而存在，因此这里也有不少涉及。这一部分很棒，不是说内容多精彩，重要的是浅显易懂。</li>
<li>第4章 是对TDD概念和模式的一些挖掘，也是期望比较大的一章，我也看到了一些精彩的论述，包括如何提高代码可测试性的手段，将测试分为基于状态和基于交互两类，等等。可惜不够过瘾，作者引申的书倒不少，自己的料不够足啊。</li>
<li>第5-8章 就是一些实际的实践了，可能也算本书的重头，包括测试web组件，数据访问组件，Swing组件，时间相关功能，以及多线程代码等等。根据自己背景需要，跳着看看就可以了。</li>
<li>第9-11章 是对验收测试驱动开发（ATDD）的介绍，是我个人，除第4章之外最喜欢的部分，因为我之前对TDD了解得不算少了，但对验收测试的了解寥寥，这部分帮助我扫盲了，也学习了一下相关工具Fit（由Wiki之父<a href="http://en.wikipedia.org/wiki/Ward_Cunningham" target="_blank">Ward Cunningham</a>开发）。</li>
<li>第12章 也是最后一章，是教你如何推行TDD，基本上是一些咨询培训的技巧，也挺有趣，不过故事少了点（作者自己还在文中强调故事的重要性，有点搞笑啊）。</li>
</ul>
<p>总得来说这是本介绍TDD和ATDD的不错的书，优点在于浅显易懂，而且有不少实践，缺点就是深度不够。</p>
<p>和TDD相关的书还有不少，顺带介绍几本不错的：</p>
<ul>
<li><a href="http://book.douban.com/subject/1771049/" target="_blank">Test Driven Development by Kent Beck</a> 极限编程之父的经典，必读</li>
<li><a href="http://book.douban.com/subject/4156589/" target="_blank">Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce</a> 我个人非常非常喜欢的一本书，他告诉了TDD就是面向对象设计，启发非常之大</li>
<li><a href="http://book.douban.com/subject/3307177/" target="_blank">Agile Testing by Lisa Crispin and Janet Gregory</a> 还没来得及读，不过看目录就心向往之。</li>
</ul>
<p>关于TDD，我最喜欢的是它的两点。第一是它能帮助我建立对自己代码的信心，让我能够保持前进而不用在潜意识里担心破坏什么东西；第二是它教会我在代码用户的角度设计API，而不是在代码中越钻越深最后竟忘了最初的需要。</p>
<p>TDD是枚不错的子弹，当然前提是你眼睛得好使。</p>
<p>最后再引申下这个关于子弹的比喻：</p>
<blockquote><p>有些大师，打猎不用枪，随手来块石头，就能搞定猎物，当然他也不排斥用子弹，不过工具对他来说不重要，因为修为在。</p>
<p>有些猎人（布道者），有一定经验了，发现对于新手来说，拿枪是最靠得住的打猎方式，因此不仅自己用，也告诉别人也去用。新人当然会虚心听取前人的意见。</p>
<p>但也有些人，见识过大师，自己也有一定经验了，就说，“大师都无视枪和子弹的，你们新人别听某些人吹牛，我自己用弓箭不也一样搞定猎物了？更何况我见过xxx就用一个石子，重要的是你们的内力⋯⋯” 新人就问“什么是内力呢？” 答，“你多写几年code就知道了。”</p>
<p>当然，一些伪布道者会完全忽视猎物的存在，嘴巴里不停地对新人喊“注意枪！注意枪！注意枪！”<em>。</em></p></blockquote>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.ituring.com.cn/"><span style="color: #0000ff;">图灵社区</span></a>，<em>原文为<a href="http://www.ituring.com.cn/article/378"><span style="color: #0000ff;">“没有银弹，但你也需要子弹——读《测试驱动开发的艺术》”</span></a>，</em></em><em>如需转载，请务必附带本声明，谢谢。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/11/07/review-on-lasse-koskela-s-tdd-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>阅读计算机图书的一些心得</title>
		<link>http://www.juvenxu.com/2011/10/25/what-i-learned-on-reading-it-books/</link>
		<comments>http://www.juvenxu.com/2011/10/25/what-i-learned-on-reading-it-books/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 18:24:06 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[总结]]></category>
		<category><![CDATA[读书]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=637</guid>
		<description><![CDATA[我是个喜欢读书的人，大学里买不起书就收集了好多电子书（盗版行为，不鼓励），工作后手头没那么拮据了，就买很多书，影印的、翻译的、国人原创的、二手的，还有一些直接从amazon.com购买的原版书，当然那个价格就相对贵很多了。到目前为止，书房一个大大的书架也已经塞了十之八九。这还不包括我在iPad上的不少阅读量。 虽然是计算机书，但大多都是随性而读，换句话说就是全凭兴趣，因而不够严肃专业，自然太深的积累是没有的，不过浅一些的心得还是可以说一说的。 首先是挑书，我在读书的同时慢慢锻炼了挑书的能力，因为读书最大的消费不是书价，而是时间，因此挑对书是至关重要的。我读书主要是看出版社，比如国外著名的有O’Reilly、Manning、Addison Wesley、Pragmatic Bookshelf等等，这些出版社的书大部分质量非常优秀，也包含了不少的经典，就算你不小心遇到本很水的，那几率也是非常地低。国内出版社和国外差距很大，但应该说一直在进步，我个人最喜欢的是东南大学出版社的O’Reilly影印系列，质量真是好得没话说，价格也公道。关于翻译，人民邮电图灵的质量应该是做得最好的了，特别是有阮一峰这样的译者，真是读者的福气。原创方面的话，应该说机械工业的华章和电子工业的博文视点强一点，经常会出现一些让人眼前一亮的书，其作者水平真不比老外差。 挑书还得看作者，不熟悉作者的话，那就去网店搜一下作者的名字，如果看到他有10本或者更多的著作或译作，三五年内完成，专业领域跨度又极大，那基本上这是个不负责任的家伙。计算机行业写作不是写玄幻小说，本身需要很厚的技术积累，很多专家都是积累三五年，然后再花一两年才能磨出一本好书的，因此高产的基本就无法保证质量。还有一个看作者的方法是看他有没有自己给书开辟一个网页，负责的作者会把自己的书看得很重，因此写完了也会持续收集反馈。 挑书当然也可以看网店的书评，什么China-Pub啊、当当啊、京东啊、卓越啊、豆瓣啊等等，但不是所有书评都是可以相信的，书拖书黑在这个年代就像火车站卖发票的贩子一样常见。我个人会关注那些购买了书后，写得较长的有理有据的书评。什么“好书，顶”，或者“垃圾、骗子”这样的评论其实等于什么都没说。看看amazon.com上的书评，好在哪里、不好在哪里，说得清清楚楚，那才是有意义的。 挑到了好书就开始享受咯！我会大概把书分为简单两类，其一是硬技术，例如一门语言ruby，一个技术lucene，不学就不会，学了就会。对这类书，会有两种阅读的驱动力，一是完全凭兴趣，例如前一阵子因为《黑客与画家》的缘故，想学学lisp了，那就找本lisp的书看看，又或者因为最近买了mac，就找本mac编程的书看看，等等。二是功利性阅读了，例如最近一个项目要用到lucene，那就找本lucene的书来啃，以应付工作。功利和兴趣还是结合起来的好，完全功利了就没有自己的想法，完全凭兴趣那也不太现实，毕竟还是要工作的。当然，如果工作的技术点就是你的兴趣，那再好不过。 除了硬技术类书籍，还有大量软技术的书籍。最好的例子就是《程序员修炼之道》，它没说某个特定的技术，但总结了大量闪光的思想，可能读到其中一条你会有豁然开朗的感觉，又或者你读的时候没在意，一段时间后在实际工作中遇到的问题让你想起书中的一些建议。出版社可能会将其归入“技术人文类”，但我觉得，所有那些看过一遍都要思考理解后才能慢慢感悟的书都属于“软技术”，例如《重构》也算，还有一些软件工程类的如敏捷开发等等。 我会夹杂着读硬技术书籍和软技术书籍，相对来说软技术书籍读起来会轻松一点，因为表面意思理解很容易，而硬技术，懂就是懂，不懂就是不懂，前后还有衔接，要求你硬记住，或者实际操作才能理解。但其实真正理解软技术更难，这些书往往需要你读过一遍之后，过一年再读，再过几年再读，才能理解作者的思想。当然读太多这类的书而忽于实践也不好，到最后只剩下空洞的理论。功利性的阅读往往只再硬技术上，但如果缺乏软技术的补充，往往会迷失，好比已经积累了很多内力但缺乏调理。 书读得多了，我渐渐有了点怪癖，例如追求原版书的印刷质量，有时候会不惜好几倍的价格买原版书。又或者一直盯着市场看有什么好书出来，有了就买，到最后都来不及读。还有就是能读英文就不读翻译，完全是盲目的。其实只要翻译够好，读起来也爽，还能节省时间。不过话说回来，作为一个程序员，读个至少十本八本的英文版还是有必要的，这点能力是必须的。 读书的时候做点笔记也大有帮助，给自己买本漂亮的笔记本，多少写写划划，电子版的话，很多软件如iPad平台上的，都支持做些笔记。这都帮助思考，而不是简单的字面意思都过掉了，以为读完了，其实理解甚少。 大概想到的就这么多了，最后给大家的建议是，只要是你认定的好书，读一遍肯定是不够的，一定要读个两到三遍！ 本文已经首发于图灵社区，原文为《阅读计算机图书的一些心得》，如需转载，请务必附带本声明，谢谢。]]></description>
			<content:encoded><![CDATA[<p>我是个喜欢读书的人，大学里买不起书就收集了好多电子书（盗版行为，不鼓励），工作后手头没那么拮据了，就买很多书，影印的、翻译的、国人原创的、二手的，还有一些直接从amazon.com购买的原版书，当然那个价格就相对贵很多了。到目前为止，书房一个大大的书架也已经塞了十之八九。这还不包括我在iPad上的不少阅读量。</p>
<p>虽然是计算机书，但大多都是随性而读，换句话说就是全凭兴趣，因而不够严肃专业，自然太深的积累是没有的，不过浅一些的心得还是可以说一说的。</p>
<p>首先是挑书，我在读书的同时慢慢锻炼了挑书的能力，因为读书最大的消费不是书价，而是时间，因此挑对书是至关重要的。我读书主要是看出版社，比如国外著名的有O’Reilly、Manning、Addison Wesley、Pragmatic Bookshelf等等，这些出版社的书大部分质量非常优秀，也包含了不少的经典，就算你不小心遇到本很水的，那几率也是非常地低。国内出版社和国外差距很大，但应该说一直在进步，我个人最喜欢的是东南大学出版社的O’Reilly影印系列，质量真是好得没话说，价格也公道。关于翻译，人民邮电图灵的质量应该是做得最好的了，特别是有阮一峰这样的译者，真是读者的福气。原创方面的话，应该说机械工业的华章和电子工业的博文视点强一点，经常会出现一些让人眼前一亮的书，其作者水平真不比老外差。</p>
<p>挑书还得看作者，不熟悉作者的话，那就去网店搜一下作者的名字，如果看到他有10本或者更多的著作或译作，三五年内完成，专业领域跨度又极大，那基本上这是个不负责任的家伙。计算机行业写作不是写玄幻小说，本身需要很厚的技术积累，很多专家都是积累三五年，然后再花一两年才能磨出一本好书的，因此高产的基本就无法保证质量。还有一个看作者的方法是看他有没有自己给书开辟一个网页，负责的作者会把自己的书看得很重，因此写完了也会持续收集反馈。</p>
<p>挑书当然也可以看网店的书评，什么China-Pub啊、当当啊、京东啊、卓越啊、豆瓣啊等等，但不是所有书评都是可以相信的，书拖书黑在这个年代就像火车站卖发票的贩子一样常见。我个人会关注那些购买了书后，写得较长的有理有据的书评。什么“好书，顶”，或者“垃圾、骗子”这样的评论其实等于什么都没说。看看amazon.com上的书评，好在哪里、不好在哪里，说得清清楚楚，那才是有意义的。</p>
<p>挑到了好书就开始享受咯！我会大概把书分为简单两类，其一是硬技术，例如一门语言ruby，一个技术lucene，不学就不会，学了就会。对这类书，会有两种阅读的驱动力，一是完全凭兴趣，例如前一阵子因为《<a href="http://www.turingbook.com/book/39" target="_blank">黑客与画家</a>》的缘故，想学学lisp了，那就找本lisp的书看看，又或者因为最近买了mac，就找本mac编程的书看看，等等。二是功利性阅读了，例如最近一个项目要用到lucene，那就找本lucene的书来啃，以应付工作。功利和兴趣还是结合起来的好，完全功利了就没有自己的想法，完全凭兴趣那也不太现实，毕竟还是要工作的。当然，如果工作的技术点就是你的兴趣，那再好不过。</p>
<p>除了硬技术类书籍，还有大量软技术的书籍。最好的例子就是《程序员修炼之道》，它没说某个特定的技术，但总结了大量闪光的思想，可能读到其中一条你会有豁然开朗的感觉，又或者你读的时候没在意，一段时间后在实际工作中遇到的问题让你想起书中的一些建议。出版社可能会将其归入“技术人文类”，但我觉得，所有那些看过一遍都要思考理解后才能慢慢感悟的书都属于“软技术”，例如《<a href="http://www.turingbook.com/book/211" target="_blank">重构</a>》也算，还有一些软件工程类的如敏捷开发等等。</p>
<p>我会夹杂着读硬技术书籍和软技术书籍，相对来说软技术书籍读起来会轻松一点，因为表面意思理解很容易，而硬技术，懂就是懂，不懂就是不懂，前后还有衔接，要求你硬记住，或者实际操作才能理解。但其实真正理解软技术更难，这些书往往需要你读过一遍之后，过一年再读，再过几年再读，才能理解作者的思想。当然读太多这类的书而忽于实践也不好，到最后只剩下空洞的理论。功利性的阅读往往只再硬技术上，但如果缺乏软技术的补充，往往会迷失，好比已经积累了很多内力但缺乏调理。</p>
<p>书读得多了，我渐渐有了点怪癖，例如追求原版书的印刷质量，有时候会不惜好几倍的价格买原版书。又或者一直盯着市场看有什么好书出来，有了就买，到最后都来不及读。还有就是能读英文就不读翻译，完全是盲目的。其实只要翻译够好，读起来也爽，还能节省时间。不过话说回来，作为一个程序员，读个至少十本八本的英文版还是有必要的，这点能力是必须的。</p>
<p>读书的时候做点笔记也大有帮助，给自己买本漂亮的笔记本，多少写写划划，电子版的话，很多软件如iPad平台上的，都支持做些笔记。这都帮助思考，而不是简单的字面意思都过掉了，以为读完了，其实理解甚少。</p>
<p>大概想到的就这么多了，最后给大家的建议是，只要是你认定的好书，读一遍肯定是不够的，一定要读个两到三遍！</p>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.ituring.com.cn/"><span style="color: #0000ff;">图灵社区</span></a>，<em>原文为<a href="http://www.ituring.com.cn/article/22"><span style="color: #0000ff;">《阅读计算机图书的一些心得》</span></a>，</em></em><em>如需转载，请务必附带本声明，谢谢。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/10/25/what-i-learned-on-reading-it-books/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>May your builds always succeeds!</title>
		<link>http://www.juvenxu.com/2011/10/06/may-your-builds-always-succeeds/</link>
		<comments>http://www.juvenxu.com/2011/10/06/may-your-builds-always-succeeds/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 15:36:37 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[书]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[书评]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=624</guid>
		<description><![CDATA[Just finished the book &#8220;Building and Testing with Gradle&#8221; 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 [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-medium wp-image-625 alignright" style="margin: 2px; border: 1px solid black;" title="gradle-book" src="http://www.juvenxu.com/wp-content/uploads/2011/10/gradle-book-227x300.jpg" alt="" width="227" height="300" /></p>
<p>Just finished the book &#8220;Building and Testing with Gradle&#8221; in this vacation, and here is my review.</p>
<p>First of all this book has a great Foreword by Ken Sipe, the CTO of Gradleware. I totally agree with him on</p>
<blockquote><p>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&#8217;t a great build tool for Java is that it didn&#8217;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 &#8220;the one model to rule them all&#8221;. You&#8217;re able to express your build needs within that model and only that model.</p>
<p>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.</p></blockquote>
<p>To simplify, <em>Make has no build model, Ant has weak model, Maven has one (and only one) strong model, and Gradle allows you do define model. </em>I&#8217;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 &#8216;model&#8217; concept is the key to undertand the differences among those tools.</p>
<p>BTW, the title of this post if borrowed from Ken&#8217;s foreword <img src='http://www.juvenxu.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>This is one of the shortest technique book I&#8217;ve ever read, only 110 pages composed by 6 chapters:</p>
<ol>
<li>Hello, Gradle!</li>
<li>Gradle Tasks</li>
<li>Ant and Gradle</li>
<li>Maven and Gradle</li>
<li>Testing with Gradle</li>
<li>Multiproject Builds</li>
</ol>
<p>Just like any tool introduction book, the first chapter is for the very beginners. The &#8216;Gradle Tasks&#8217; 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 &#8216;Maven and Gradle&#8217; 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 &#8216;Testing with Gradle&#8217; has little value, it&#8217;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&#8217;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 <img src='http://www.juvenxu.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> .</p>
<p>Too short the book is so sometimes I have to refer to the <a href="http://www.gradle.org/current/docs/userguide/userguide.html">official gradle user guide</a> 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&#8217;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.</p>
<p>Thanks to Tim Berglund &amp; Matthew McCullough for making this book out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/10/06/may-your-builds-always-succeeds/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>InfoQ Maven专栏（十）——Maven 3，是时候升级了</title>
		<link>http://www.juvenxu.com/2011/08/05/infoq-maven-time-to-upgrade-to-maven3/</link>
		<comments>http://www.juvenxu.com/2011/08/05/infoq-maven-time-to-upgrade-to-maven3/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 18:56:54 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[Maven]]></category>
		<category><![CDATA[InfoQ]]></category>
		<category><![CDATA[InfoQ Maven专栏]]></category>
		<category><![CDATA[Maven 3]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=619</guid>
		<description><![CDATA[去年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个线程进行构建： $ mvn -T 4 clean install $ mvn -T 1C clean install Maven的提交者之一Anders Hammar在其文章迁移到Maven 3的十大理由中介绍了一个简单的实验，分别用Maven 2.2.1，Maven 3.0.2（单线程），和Maven 3.0.2（4线程）构建同样的包含32个模块的Maven源代码，得到了如下的结果： Table 1. 用&#8221;mvn package&#8221;构建Maven SCM trunk（32个模块） 时间/内存 Maven [...]]]></description>
			<content:encoded><![CDATA[<p>去年10月份Apache Maven发布了3.0正式版，而在上个月的22号，<a href="http://www.eclipse.org/org/press-release/20110622indigo.php">Eclipse基金会宣布了Eclipse 3.7（Indigo）</a>的发布，该版本Eclipse最大的新特性之一就是集成了Maven。下载<a href="http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/indigor">Eclipse IDE for Java Developers</a>版 本的用户会发现，Eclipse已经能够自动识别Maven项目了。Indigo中内置的Maven版本是3.0.2，这在一定程度上说明Maven  3已经非常稳定了。不过我相信一定还有很多Maven 2用户在犹豫是否升级，本文会介绍一些Maven  3最重要的特性，旨在帮助读者扫除疑虑，尽早享受Maven 3所能带来的各种便利。</p>
<h2>确保兼容性</h2>
<p>在升级软件的时候，兼容性显然是首先要考虑的问题，如果原本在Maven 2下能成功构建的项目，在Maven  3下立刻就失败了，而且难以简单修复，那显然是不可接受的。 好在Maven用户大可打消这一顾虑，Maven 3自设计之初就一直考虑与Maven  2的兼容性，这不仅是指兼容Maven  2的核心，还包括大量的org.apache.maven.plugins与org.codehaus.mojo插件。虽然由于某些插件代码的特殊性，无 法做到100%完全的兼容，但已经基本不会遇到问题了。</p>
<p>如果你还有担心，那可以先仔细阅读官方发布的<a href="https://cwiki.apache.org/MAVEN/maven-3x-compatibility-notes.html">Maven 3.x兼容性笔记</a>和<a href="https://cwiki.apache.org/MAVEN/maven-3x-plugin-compatibility-matrix.html">Maven 3.x插件兼容性列表</a>。这两份文档记录的兼容性问题主要涉及的是一些应当被弃用的特性，并且都给出了Maven 3下的解决方案。</p>
<h2>改进性能</h2>
<p>Maven 3的性能较之于Maven 2是有了很大的进步的，这体现在内存占用的减少和构建时间的减少两个方面。特别是Maven 3引入的<a href="https://cwiki.apache.org/MAVEN/parallel-builds-in-maven-3.html">并行构建特性</a>，能够分析项目模块之间的依赖关系，然后并行地构建那些相互间没有依赖关系的模块，从而充分利用如今普遍的多核CPU资源。</p>
<p>以下两条命令分别表示用4个线程构建，以及根据CPU核数每个核分配1个线程进行构建：</p>
<pre>$ mvn -T 4 clean install
$ mvn -T 1C clean install</pre>
<p>Maven的提交者之一Anders Hammar在其文章<a href="http://www.sonatype.com/people/2011/02/top-ten-reasons-to-move-to-maven-3/">迁移到Maven 3的十大理由</a>中介绍了一个简单的实验，分别用Maven 2.2.1，Maven 3.0.2（单线程），和Maven 3.0.2（4线程）构建同样的包含32个模块的Maven源代码，得到了如下的结果：</p>
<table id="d0e1180" border="1">
<caption>Table 1. 用&#8221;mvn package&#8221;构建Maven SCM trunk（32个模块）</caption>
<tbody>
<tr>
<td></td>
<td>时间/内存</td>
</tr>
<tr>
<td>Maven 2.2.1</td>
<td>3:20/53M</td>
</tr>
<tr>
<td>Maven 3.0.2（单线程）</td>
<td>3:15/27M</td>
</tr>
<tr>
<td>Maven 3.0.2（4线程）</td>
<td>2:26/28M</td>
</tr>
</tbody>
</table>
<p>可以看到Maven 3下内存的占用减少了近一半！而开启并行构建后，时间的节省也是非常可观的。而项目越大，这种性能的改进就越为明显。如果你的开发环境没有充裕的内存，而你的项目又非常大，那光内存节省这一条就足以让你立刻转向Maven 3了。</p>
<h2>改进模块间依赖解析</h2>
<p>Maven  2中一个比较令人头疼的问题是，当你在构建一个多模块项目的时候，为了使前面的模块能在后面模块classpath中生效，你必须将其install到本 地仓库中之后，Maven才能解析使用。几乎所有Maven 2用户或早或晚都遇到了这个困惑，“为什么我已经 mvn clean package  了模块A，可构建模块B的时候还是无法看到A的更新呢？”这个问题在Maven 3中得以解决了，在构建多模块项目的时候，Maven  3会从反应堆（reactor）中解析模块间依赖，也就是说只要模块A执行了package，那模块B就能根据相对路径找到并解析使用A生成的jar文 件。</p>
<h2>提倡最佳实践</h2>
<p>刚从Maven 2转到Maven 3的用户很可能会发现执行构建的时候命令行会打印很多如下的警告：</p>
<pre>[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-javadoc-plugin is missing.
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.</pre>
<p>大部分如下的警告是因为用户在配置插件或者依赖的时候没有指定版本，无法保证<a href="../2010/05/07/reproducibility-of-maven-build/">构建的可重现性</a>，从而为构建引入了潜在的风险。这样的警告是一种既保持兼容性，又提倡最佳实践而做出的权衡。类似的改进还包括弃用profile.xml特性、明确分离项目依赖和插件依赖等等。</p>
<h2>改进日志输出</h2>
<p>这是一个很微小的改进，却突显了Maven开发者对Maven用户的关怀，我个人非常喜欢这点改进。简单得来说，Maven  3的构建日志更容易阅读了。插件的输出之间都有空行隔开，每个被运行插件的版本、目标、以及所处模块的artifactId都得以清晰显示。当构建出现错 误的时候，这样的输出能帮助用户更快地找到问题所在。</p>
<h2>站点（注意！）</h2>
<p>站点这一特性是Maven 2的核心，但是在Maven 3中，该特性被完全移到了maven-site-plugin中，这就导致了相关的配置也需要转移。Maven 2中与站点相关的配置是在POM的reporting元素下的，如：</p>
<pre>&lt;project&gt;
  ...
  &lt;reporting&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.7&lt;/version&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/reporting&gt;
&lt;/project&gt;</pre>
<p>在Maven 3中，所有站点相关的配置都应该出现在maven-site-plugin下面：</p>
<pre>&lt;project&gt;
 ...
 &lt;build&gt;
   ...
   &lt;plugins&gt;
     ...
     &lt;plugin&gt;
       &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
       &lt;artifactId&gt;maven-site-plugin&lt;/artifactId&gt;
       &lt;version&gt;3.0-beta-3&lt;/version&gt;
       &lt;configuration&gt;
         &lt;reportPlugins&gt;
           &lt;plugin&gt;
             &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
             &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
             &lt;version&gt;2.7&lt;/version&gt;
           &lt;/plugin&gt;
         &lt;/reportPlugins&gt;
       &lt;/configuration&gt;
     &lt;/plugin&gt;
   &lt;/plugins&gt;
 &lt;/build&gt;
&lt;/project&gt;</pre>
<h2>小结与致谢</h2>
<p>本文从兼容性、新特性、性能改进、以及重要细节等方面全面介绍了Maven 3。Maven 3是Maven从成熟走向巅峰的标志，如果你还未升级，我强烈建议你至少尝试一下，Maven的安装是非常简单的，只需要下载一个zip包、解压、然后设置简单的环境变量即可，<a href="http://maven.apache.org/download.html">马上去下载吧</a>！</p>
<p>由于能力及精力所限，我已经很难再写更多既不重复又符合很多读者口味的Maven文章，因此暂且计划将该专栏告一段落。我衷心感谢张凯峰的策划和编 辑，感谢读者的支持，另外也感谢我的家人，特别是我三岁的女儿，那些给写稿的时间本该属于她们。最后，我还是会持续关心  Maven的发展，有机会也一定会分享更多的经验和心得。</p>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>，版权所有，<em>原文为</em><a href="http://www.infoq.com/cn/news/2011/07/xxb-maven-10-time-to-update">《Maven实战（ 十）——Maven 3，是时候升级了》</a></em><em><em>，</em>如需转载，请务必附带本声明，谢谢。<br />
<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>是一个面向中高端技术人员的在线独立社区，为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如<a href="http://www.qconbeijing.com/" target="_blank">QCon</a> 、线下技术交流活动<a title="QClub" href="http://www.infoq.com/cn/qclub" target="_blank">QClub</a>、免费迷你书下载如<a title="《架构师 》" href="http://www.infoq.com/cn/architect" target="_blank">《</a><a href="http://www.infoq.com/cn/architect" target="_blank">架构师</a>》等。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/08/05/infoq-maven-time-to-upgrade-to-maven3/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>InfoQ Maven专栏（九）——打包的技巧</title>
		<link>http://www.juvenxu.com/2011/08/05/infoq-maven-packag/</link>
		<comments>http://www.juvenxu.com/2011/08/05/infoq-maven-packag/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 18:49:41 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[Maven]]></category>
		<category><![CDATA[InfoQ]]></category>
		<category><![CDATA[InfoQ Maven专栏]]></category>
		<category><![CDATA[maven插件]]></category>
		<category><![CDATA[打包]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=615</guid>
		<description><![CDATA[“打包“这个词听起来比较土，比较正式的说法应该是”构建项目软件包“，具体说就是将项目中的各种文件，比如源代码、编译生成的字节码、配置文件、文档，按照规范的格式生成归档，最常见的当然就是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操作，会看到如下的输出： [INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ git-demo --- [INFO] Building jar: /home/juven/git_juven/git-demo/target/git-demo-1.2-SNAPSHOT.jar 相比之下，对一个war项目执行mvn package操作，输出是这样的： [INFO] --- maven-war-plugin:2.1:war (default-war) @ webapp-demo --- [INFO] Packaging webapp [INFO] Assembling webapp [webapp-demo] in [/home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT] [INFO] Processing war project [INFO] Copying webapp resources [/home/juven/git_juven/webapp-demo/src/main/webapp] [INFO] Webapp assembled in [90 msecs] [...]]]></description>
			<content:encoded><![CDATA[<p>“打包“这个词听起来比较土，比较正式的说法应该是”构建项目软件包“，具体说就是将项目中的各种文件，比如源代码、编译生成的字节码、配置文件、文档，按照规范的格式生成归档，最常见的当然就是JAR包和WAR包了，复杂点的例子是<a href="http://maven.apache.org/download.html">Maven官方下载页面的分发包</a>， 它有自定义的格式，方便用户直接解压后就在命令行使用。作为一款”打包工具“，Maven自然有义务帮助用户创建各种各样的包，规范的JAR包和WAR包 自然不再话下，略微复杂的自定义打包格式也必须支持，本文就介绍一些常用的打包案例以及相关的实现方式，除了前面提到的一些包以外，你还能看到如何生成源 码包、Javadoc包、以及从命令行可直接运行的CLI包。</p>
<h2>Packaging的含义</h2>
<p>任何一个Maven项目都需要定义POM元素packaging（如果不写则默认值为jar）。顾名思义，该元素决定了项目的打包方式。实际的情形 中，如果你不声明该元素，Maven会帮你生成一个JAR包；如果你定义该元素的值为war，那你会得到一个WAR包；如果定义其值为POM（比如是一个 父模块），那什么包都不会生成。除此之外，Maven默认还支持一些其他的流行打包格式，例如ejb3和ear。你不需要了解具体的打包细节，你所需要做 的就是告诉Maven，”我是个什么类型的项目“，这就是<strong>约定优于配置</strong>的力量。</p>
<p>为了更好的理解Maven的默认打包方式，我们不妨来看看简单的声明背后发生了什么，对一个jar项目执行mvn package操作，会看到如下的输出：</p>
<pre>[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ git-demo ---
[INFO] Building jar: /home/juven/git_juven/git-demo/target/git-demo-1.2-SNAPSHOT.jar</pre>
<p>相比之下，对一个war项目执行mvn package操作，输出是这样的：</p>
<pre>[INFO] --- maven-war-plugin:2.1:war (default-war) @ webapp-demo ---
[INFO] Packaging webapp
[INFO] Assembling webapp [webapp-demo] in [/home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/home/juven/git_juven/webapp-demo/src/main/webapp]
[INFO] Webapp assembled in [90 msecs]
[INFO] Building war: /home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT.war</pre>
<p>对应于同样的package生命周期阶段，Maven为jar项目调用了maven-jar-plugin，为war项目调用了maven-war-plugin，换言之，<strong>packaging直接影响Maven的构建生命周期</strong>。了解这一点非常重要，特别是当你需要自定义打包行为的时候，你就必须知道去配置哪个插件。一个常见的例子就是在打包war项目的时候排除某些web资源文件，这时就应该配置maven-war-plugin如下：</p>
<pre>&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.1.1&lt;/version&gt;
    &lt;configuration&gt;
      &lt;webResources&gt;
        &lt;resource&gt;
          &lt;directory&gt;src/main/webapp&lt;/directory&gt;
          &lt;excludes&gt;
            &lt;exclude&gt;**/*.jpg&lt;/exclude&gt;
          &lt;/excludes&gt;
        &lt;/resource&gt;
      &lt;/webResources&gt;
    &lt;/configuration&gt;
  &lt;/plugin&gt;</pre>
<h2>源码包和Javadoc包</h2>
<p>本专栏的<a href="http://www.infoq.com/cn/news/2010/12/xxb-maven-1">《坐标规划》</a>一 文中曾解释过，一个Maven项目只生成一个主构件，当需要生成其他附属构件的时候，就需要用上classifier。源码包和Javadoc包就是附属 构件的极佳例子。它们有着广泛的用途，尤其是源码包，当你使用一个第三方依赖的时候，有时候会希望在IDE中直接进入该依赖的源码查看其实现的细节，如果 该依赖将源码包发布到了Maven仓库，那么像Eclipse就能通过m2eclipse插件解析下载源码包并关联到你的项目中，十分方便。由于生成源码 包是极其常见的需求，因此Maven官方提供了一个插件来帮助用户完成这个任务：</p>
<pre>  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-source-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.1.2&lt;/version&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;id&gt;attach-sources&lt;/id&gt;
        &lt;phase&gt;verify&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;jar-no-fork&lt;/goal&gt;
        &lt;/goals&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;</pre>
<p>类似的，生成Javadoc包只需要配置插件如下：</p>
<pre>  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.7&lt;/version&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;id&gt;attach-javadocs&lt;/id&gt;
          &lt;goals&gt;
            &lt;goal&gt;jar&lt;/goal&gt;
          &lt;/goals&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;</pre>
<p>为了帮助所有Maven用户更方便的使用Maven中央库中海量的资源，中央仓库的维护者强制要求开源项目提交构件的时候同时提供源码包和Javadoc包。这是个很好的实践，读者也可以尝试在自己所处的公司内部实行，以促进不同项目之间的交流。</p>
<h2>可执行CLI包</h2>
<p>除了前面提到了常规JAR包、WAR包，源码包和Javadoc包，另一种常被用到的包是在命令行可直接运行的CLI（Command  Line）包。默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件，而要得到一个可以直接在命令行通过java命令运行的 JAR文件，还要满足两个条件：</p>
<ul>
<li>JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。</li>
<li>项目所有的依赖都必须在Classpath中。</li>
</ul>
<p>Maven有好几个插件能帮助用户完成上述任务，不过用起来最方便的还是<a href="http://maven.apache.org/plugins/maven-shade-plugin/">maven-shade-plugin</a>， 它可以让用户配置Main-Class的值，然后在打包的时候将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖，它很聪明地将依 赖JAR文件全部解压后，再将得到的.class文件连同当前项目的.class文件一起合并到最终的CLI包中，这样，在执行CLI  JAR文件的时候，所有需要的类就都在Classpath中了。下面是一个配置样例：</p>
<pre>  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
    &lt;version&gt;1.4&lt;/version&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;phase&gt;package&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;shade&lt;/goal&gt;
        &lt;/goals&gt;
        &lt;configuration&gt;
          &lt;transformers&gt;
            &lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&gt;
              &lt;mainClass&gt;com.juvenxu.mavenbook.HelloWorldCli&lt;/mainClass&gt;
            &lt;/transformer&gt;
          &lt;/transformers&gt;
        &lt;/configuration&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;</pre>
<p>上述例子中的，我的Main-Class是com.juvenxu.mavenbook.HelloWorldCli，构建完成后，对应于一个常规 的hello-world-1.0.jar文件，我还得到了一个hello-world-1.0-cli.jar文件。细心的读者可能已经注意到了，这里 用的是cli这个classifier。最后，我可以通过<strong>java -jar hello-world-1.0-cli.jar</strong>命令运行程序。</p>
<h2>自定义格式包</h2>
<p>实际的软件项目常常会有更复杂的打包需求，例如我们可能需要为客户提供一份产品的分发包，这个包不仅仅包含项目的字节码文件，还得包含依赖以及相关脚本文件以方便客户解压后就能运行，此外分发包还得包含一些必要的文档。这时项目的源码目录结构大致是这样的：</p>
<pre>pom.xml
src/main/java/
src/main/resources/
src/test/java/
src/test/resources/
src/main/scripts/
src/main/assembly/
README.txt</pre>
<p>除了基本的pom.xml和一般Maven目录之外，这里还有一个src/main/scripts/目录，该目录会包含一些脚本文件如 run.sh和run.bat，src/main/assembly/会包含一个assembly.xml，这是打包的描述文件，稍后介绍，最后的 README.txt是份简单的文档。</p>
<p>我们希望最终生成一个zip格式的分发包，它包含如下的一个结构：</p>
<pre>bin/
lib/
README.txt</pre>
<p>其中bin/目录包含了可执行脚本run.sh和run.bat，lib/目录包含了项目JAR包和所有依赖JAR，README.txt就是前面提到的文档。</p>
<p>描述清楚需求后，我们就要搬出Maven最强大的打包插件：<a href="http://maven.apache.org/plugins/maven-assembly-plugin/">maven-assembly-plugin</a>。 它支持各种打包文件格式，包括zip、tar.gz、tar.bz2等等，通过一个打包描述文件（该例中是src/main /assembly.xml），它能够帮助用户选择具体打包哪些文件集合、依赖、模块、和甚至本地仓库文件，每个项的具体打包路径用户也能自由控制。如下 就是对应上述需求的打包描述文件src/main/assembly.xml：</p>
<pre>&lt;assembly&gt;
  &lt;id&gt;bin&lt;/id&gt;
  &lt;formats&gt;
    &lt;format&gt;zip&lt;/format&gt;
  &lt;/formats&gt;
  &lt;dependencySets&gt;
    &lt;dependencySet&gt;
      &lt;useProjectArtifact&gt;true&lt;/useProjectArtifact&gt;
      &lt;outputDirectory&gt;lib&lt;/outputDirectory&gt;
    &lt;/dependencySet&gt;
  &lt;/dependencySets&gt;
  &lt;fileSets&gt;
    &lt;fileSet&gt;
      &lt;outputDirectory&gt;/&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;README.txt&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
    &lt;fileSet&gt;
      &lt;directory&gt;src/main/scripts&lt;/directory&gt;
      &lt;outputDirectory&gt;/bin&lt;/outputDirectory&gt;
      &lt;includes&gt;
        &lt;include&gt;run.sh&lt;/include&gt;
        &lt;include&gt;run.bat&lt;/include&gt;
      &lt;/includes&gt;
    &lt;/fileSet&gt;
  &lt;/fileSets&gt;
&lt;/assembly&gt;</pre>
<ul>
<li>首先这个assembly.xml文件的id对应了其最终生成文件的classifier。</li>
<li>其次formats定义打包生成的文件格式，这里是zip。因此结合id我们会得到一个名为hello-world-1.0-bin.zip的文件。（假设artifactId为hello-world，version为1.0）</li>
<li>dependencySets用来定义选择依赖并定义最终打包到什么目录，这里我们声明的一个depenencySet默认包含所有所有 依赖，而useProjectArtifact表示将项目本身生成的构件也包含在内，最终打包至输出包内的lib路径下（由 outputDirectory指定）。</li>
<li>fileSets允许用户通过文件或目录的粒度来控制打包。这里的第一个fileSet打包README.txt文件至包的根目录下，第二个fileSet则将src/main/scripts下的run.sh和run.bat文件打包至输出包的bin目录下。</li>
</ul>
<p>打包描述文件所支持的配置远超出本文所能覆盖的范围，为了避免读者被过多细节扰乱思维，这里不再展开，读者若有需要可以去参考<a href="http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html">这份文档</a>。</p>
<p>最后，我们需要配置maven-assembly-plugin使用打包描述文件，并绑定生命周期阶段使其自动执行打包操作：</p>
<pre>  &lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.2.1&lt;/version&gt;
    &lt;configuration&gt;
      &lt;descriptors&gt;
        &lt;descriptor&gt;src/main/assembly/assembly.xml&lt;/descriptor&gt;
      &lt;/descriptors&gt;
    &lt;/configuration&gt;
    &lt;executions&gt;
      &lt;execution&gt;
        &lt;id&gt;make-assembly&lt;/id&gt;
        &lt;phase&gt;package&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;single&lt;/goal&gt;
        &lt;/goals&gt;
      &lt;/execution&gt;
    &lt;/executions&gt;
  &lt;/plugin&gt;</pre>
<p>运行<strong>mvn clean package</strong>之后，我们就能在target/目录下得到名为hello-world-1.0-bin.zip的分发包了。</p>
<h2>小结</h2>
<p>打包是项目构建最重要的组成部分之一，本文介绍了主流Maven打包技巧，包括默认打包方式的原理、如何制作源码包和Javadoc包、如何制作命 令行可运行的CLI包、以及进一步的，如何基于个性化需求自定义打包格式。这其中涉及了很多的Maven插件，当然最重要，也是最为复杂和强大的打包插件 就是maven-assembly-plugin。事实上Maven本身的分发包就是通过maven-assembly-plugin制作的，感兴趣的读 者可以直接<a href="http://svn.apache.org/viewvc/maven/maven-3/trunk/apache-maven/src/main/assembly/">查看源码</a>一窥究竟。</p>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>，版权所有，<em>原文为</em><a href="http://www.infoq.com/cn/news/2011/06/xxb-maven-9-package">《Maven实战（九）——打包的技巧》</a></em><em><em>，</em>如需转载，请务必附带本声明，谢谢。<br />
<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>是一个面向中高端技术人员的在线独立社区，为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如<a href="http://www.qconbeijing.com/" target="_blank">QCon</a> 、线下技术交流活动<a title="QClub" href="http://www.infoq.com/cn/qclub" target="_blank">QClub</a>、免费迷你书下载如<a title="《架构师 》" href="http://www.infoq.com/cn/architect" target="_blank">《</a><a href="http://www.infoq.com/cn/architect" target="_blank">架构师</a>》等。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/08/05/infoq-maven-packag/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>使用email-ext替换Jenkins(Hudson)的默认邮件通知</title>
		<link>http://www.juvenxu.com/2011/05/18/hudson-email-ext/</link>
		<comments>http://www.juvenxu.com/2011/05/18/hudson-email-ext/#comments</comments>
		<pubDate>Wed, 18 May 2011 06:56:02 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[持续集成]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=594</guid>
		<description><![CDATA[注：本文由Jdonee投递 简述 众所周知，Jenkins(Hudson)默认提供了一个邮件通知，能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性，比如它的邮件通知无法提供详细的邮件内容、无法定义发送邮件的格式、无法定义灵活的邮件接收配置等等。在这样的情况下，我们找到了Jenkins Email Extension Plugin。该插件能允许你自定义邮件通知的方方面面，比如在发送邮件时你可以自定义发送给谁，发送具体什么内容等等。本文不会告诉你如何安装该插件，关于插件的安装请参考这里。 功能概要 该插件扩展了Hudson构建默认的邮件通知功能，并赋予你更多更灵活的控制。它能在如下三块区域来自定义： Triggers -指定发送一封邮件通知应有的前置条件。 Content - 指定每封触发邮件的标题和正文的内容。 Recipients -.指定一封邮件触发后发送给谁来接收(邮件)。 配置 它主要包含两个部分：基本配置和项目配置。 公共配置 当然，在一个项目中应用email-ext插件之前，您必须做一些公共的配置。现在先跳转到Hudson的“系统配置”页面，如下图： 找到标题为“Extended E-mail Notification”的片段，你就能配置一些公共的email-ext属性。这些属性必须匹配你SMTP邮件服务器的设置。这一节不仅能配置成Hudson原有邮件通知的镜像(虽然有很多配置是一样的，但这是个不同的扩展点)，而且还增加了一些额外的功能。输入框中名为 Default Subject 和 Default Content 的项允许你在公共级别配置邮件的内容。这样做的话，可以使您为所有的项目按您的需求做更好的、更简单的配置。如下图。 根据帮助文档，我们可以了解到一些公共属性，下面我解释一下常用的属性。 属性详解： Override Global Settings 如果不选，该插件将使用默认的E-mail Notification通知选项。反之，您可以通过指定不同于( 默认选项)的设置来进行覆盖。 Default Content Type 指定构建后发送邮件内容的类型，有Text和HTML两种. Use List-ID Email Header 为所有的邮件设置一个List-ID的邮件信头，这样你就可以在邮件客户端使用过滤。它也能阻止邮件发件人大部分的自动回复(诸如离开办公室、休假等等)。你可以使用你习惯的任何名称或者ID号，但是他们必须符合如下其中一种格式(真实的ID必须要包含在&#60;和&#62;标记里)： &#60;ci-notifications.company.org&#62; Build Notifications &#60;ci-notifications.company.org&#62; &#8220;Build Notifications&#8221; &#60;ci-notifications.company.org&#62; 关于更详细的List-ID说明请参阅RFC-2919. Default Subject 自定义邮件通知的默认主题名称。该插件能在邮件的主题字段中替换一些令牌，这样你就可以从构建中包含指定的输出信息。 [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: normal;"><em><span style="color: #008000;">注：本文由<a href="http://www.jdonee.com/">Jdonee</a>投递</span></em></span></p>
<h2>简述<strong></strong></h2>
<p>众所周知，Jenkins(Hudson)默认提供了一个邮件通知，能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性，比如它的邮件通知无法提供详细的邮件内容、无法定义发送邮件的格式、无法定义灵活的邮件接收配置等等。在这样的情况下，我们找到了<a href="http://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin">Jenkins Email Extension Plugin</a>。该插件能允许你自定义邮件通知的方方面面，比如在发送邮件时你可以自定义发送给谁，发送具体什么内容等等。本文不会告诉你如何安装该插件，关于插件的安装请参考<a href="http://jdonee.iteye.com/blog/315589">这里</a>。</p>
<h2>功能概要<strong></strong></h2>
<p>该插件扩展了Hudson构建默认的邮件通知功能，并赋予你更多更灵活的控制。它能在如下三块区域来自定义：</p>
<ul>
<li><strong>Triggers</strong> -指定发送一封邮件通知应有的前置条件。</li>
<li><strong>Content</strong> - 指定每封触发邮件的标题和正文的内容。</li>
<li><strong>Recipients</strong> -.指定一封邮件触发后发送给谁来接收(邮件)。</li>
</ul>
<h2>配置<strong></strong></h2>
<p>它主要包含两个部分：基本配置和项目配置。</p>
<h4>公共配置<strong></strong></h4>
<p>当然，在一个项目中应用email-ext插件之前，您必须做一些公共的配置。现在先跳转到Hudson的“系统配置”页面，如下图：</p>
<p style="text-align: center;"><a href="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_1.jpg"><img class="aligncenter size-full wp-image-595" style="border: 1px solid black;" title="hudson_email_ext_1" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_1.jpg" alt="" width="566" height="134" /></a></p>
<p>找到标题为“<strong>Extended E-mail Notification</strong>”的片段，你就能配置一些公共的email-ext属性。这些属性必须匹配你SMTP邮件服务器的设置。这一节不仅能配置成Hudson原有邮件通知的镜像(虽然有很多配置是一样的，但这是个不同的扩展点)，而且还增加了一些额外的功能。输入框中名为 Default Subject 和 Default Content 的项允许你在公共级别配置邮件的内容。这样做的话，可以使您为所有的项目按您的需求做更好的、更简单的配置。如下图。</p>
<p style="text-align: center;"><a href="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_2.jpg"><img class="aligncenter size-full wp-image-597" style="border: 1px solid black;" title="hudson_email_ext_2" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_2.jpg" alt="" width="558" height="220" /></a></p>
<p>根据帮助文档，我们可以了解到一些公共属性，下面我解释一下常用的属性。<br />
属性详解：</p>
<ol>
<li>Override Global Settings<br />
如果不选，该插件将使用默认的E-mail Notification通知选项。反之，您可以通过指定不同于( 默认选项)的设置来进行覆盖。</li>
<li>Default Content Type<br />
指定构建后发送邮件内容的类型，有Text和HTML两种.</li>
<li>Use List-ID Email Header<br />
为所有的邮件设置一个List-ID的邮件信头，这样你就可以在邮件客户端使用过滤。它也能阻止邮件发件人大部分的自动回复(诸如离开办公室、休假等等)。你可以使用你习惯的任何名称或者ID号，但是他们必须符合如下其中一种格式(真实的ID必须要包含在&lt;和&gt;标记里)：<br />
&lt;ci-notifications.company.org&gt;<br />
Build Notifications &lt;ci-notifications.company.org&gt;<br />
&#8220;Build Notifications&#8221; &lt;ci-notifications.company.org&gt;<br />
关于更详细的List-ID说明请参阅<a href="http://www.apps.ietf.org/rfc/rfc2919.html" target="_new">RFC-2919</a>.</li>
<li>Default Subject<br />
自定义邮件通知的默认主题名称。该插件能在邮件的主题字段中替换一些令牌，这样你就可以从构建中包含指定的输出信息。</li>
<li>Default Content<br />
自定义邮件通知的默认内容主体。该插件能在邮件的内容主体中替换一些令牌，这样你就可以从构建中包含指定的输出信息。</li>
<li>Content Token Reference[公共配置]<br />
所有的参数都是可选的，每个令牌的参数可以如下表示，字符串类型使用name=“value”，而布尔型和数字型使用name=value。如果{和}标记里面没有参数，则不会被解析。<br />
示例：$TOKEN, ${TOKEN}, ${TOKEN, count=100}, ${ENV, var=&#8221;PATH&#8221;}</li>
</ol>
<h4>可用令牌</h4>
<ul>
<li><strong>${BUILD_LOG, <em>maxLines</em>, <em>escapeHtml</em>}      -</strong>显示最终构建日志。
<ul>
<li><em>maxLines</em> &#8211; 显示该日志最多显示的行数，默认250行。</li>
<li><em>escapeHtml</em> -如果为true，格式化HTML。默认false。</li>
</ul>
</li>
<li><strong>${BUILD_LOG_REGEX, <em>regex</em>, <em>linesBefore</em>,      <em>linesAfter</em>, <em>maxMatches</em>, <em>showTruncatedLines</em>, <em>substText</em>,      <em>escapeHtml</em>, <em>matchedLineHtmlStyle</em>} -</strong>按正则表达式匹配显示构建日志的行数。
<ul>
<li><em>匹配符合该正则表达式的行数。参阅</em><em>java.util.regex.Pattern</em><em>，默认</em>&#8220;(?i)\b(error|exception|fatal|fail(ed|ure)|un(defined|resolved))\b&#8221;。</li>
<li><em>linesBefore</em> -包含在匹配行之前的行编号。行数会与当前的另一个行匹配或者<em>linesAfter</em><em>重叠，默认</em><em>0</em><em>。</em></li>
<li><em>linesAfter</em> -包含在匹配行之后的行编号。行数会与当前的另一个行匹配或者<em>linesBefore</em><em>重叠，默认</em><em>0</em><em>。</em></li>
<li><em>maxMatches</em> -匹配的最大数量，如果为0，则包含所有匹配。默认为0。</li>
<li><em>showTruncatedLines</em> -如果为true，包含[...truncated ### lines...]行。默认为true。</li>
<li><em>substText</em> -如果非空，把这部分文字插入该邮件，而不是整行。默认为空。</li>
<li><em>escapeHtml</em> -如果为true，格式化HTML。默认false。</li>
<li><em>matchedLineHtmlStyle</em> -如果非空，输出HTML。匹配的行数将变为&lt;b       style=&#8221;your-style-value&#8221;&gt; html escaped matched line       &lt;/b&gt;格式。默认为空。</li>
</ul>
</li>
<li><strong>${BUILD_NUMBER} -</strong>显示当前构建的编号。</li>
<li><strong>${BUILD_STATUS} -</strong>显示当前构建的状态(失败、成功等等)</li>
<li><strong>${BUILD_URL} -</strong>显示当前构建的URL地址。</li>
<li><strong>${CHANGES, <em>showPaths</em>, <em>format</em>,      <em>pathFormat</em>} -</strong>显示上一次构建之后的变化。
<ul>
<li><em>showPaths</em> &#8211; 如果为 true,显示提交修改后的地址。默认false。</li>
<li><em>format</em> &#8211; 遍历提交信息，一个包含%X的字符串，其中%a表示作者，%d表示日期，%m表示消息，%p表示路径，%r表示版本。注意，并不是所有的版本系统都支持%d和%r。如果指定<em>showPaths</em>将被忽略<em>。默认</em>&#8220;[%a] %m\n&#8221;。</li>
<li><em>pathFormat</em> -一个包含“%p”的字符串，用来标示怎么打印字符串。</li>
</ul>
</li>
<li><strong>${CHANGES_SINCE_LAST_SUCCESS, <em>reverse</em>,      <em>format</em>, <em>showPaths</em>, <em>changesFormat</em>, <em>pathFormat</em>}      -</strong>显示上一次成功构建之后的变化。
<ul>
<li><em>reverse</em> -在顶部标示新近的构建。默认false。</li>
<li><em>format</em> -遍历构建信息，一个包含%X的字符串，其中%c为所有的改变，%n为构建编号。默认&#8221;Changes for Build #%n\n%c\n&#8221;。</li>
<li><em>showPaths</em>, <em>changesFormat</em>, <em>pathFormat</em> &#8211; 分别定义如${CHANGES}的<em>showPaths</em>、<em>format</em>和<em>pathFormat</em><em>参数。</em></li>
</ul>
</li>
<li><strong>${CHANGES_SINCE_LAST_UNSTABLE, <em>reverse</em>,      <em>format</em>, <em>showPaths</em>, <em>changesFormat</em>, <em>pathFormat</em>}      -</strong>显示显示上一次不稳固或者成功的构建之后的变化。
<ul>
<li><em>reverse</em> -在顶部标示新近的构建。默认false。</li>
<li><em>format</em> -遍历构建信息，一个包含%X的字符串，其中%c为所有的改变，%n为构建编号。默认&#8221;Changes for Build #%n\n%c\n&#8221;。</li>
<li><em>showPaths</em>, <em>changesFormat</em>, <em>pathFormat</em> -分别定义如${CHANGES}的<em>showPaths</em>、<em>format</em>和<em>pathFormat</em><em>参数。</em></li>
</ul>
</li>
<li><strong>${ENV, <em>var</em>} &#8211; </strong>显示一个环境变量。
<ul>
<li><em>var</em> &#8211; 显示该环境变量的名称。如果为空，显示所有，默认为空。</li>
</ul>
</li>
<li><strong>${FAILED_TESTS} -</strong>如果有失败的测试，显示这些失败的单元测试信息。</li>
<li><strong>${JENKINS_URL} -</strong>显示Jenkins服务器的地址。(你能在“系统配置”页改变它)。</li>
<li><strong>${HUDSON_URL} -</strong>不推荐，请使用$JENKINS_URL</li>
<li><strong>${PROJECT_NAME} -</strong>显示项目的名称。</li>
<li><strong>${PROJECT_URL} -</strong>显示项目的URL。</li>
<li><strong>${SVN_REVISION} -</strong>显示SVN的版本号。</li>
<li><strong>${CAUSE} -</strong>显示谁、通过什么渠道触发这次构建。</li>
<li><strong>${JELLY_SCRIPT, <em>template</em>} -</strong>从一个Jelly脚本模板中自定义消息内容。有两种模板可供配置：HTML和TEXT。你可以在$JENKINS_HOME/email-templates下自定义替换它。当使用自动义模板时，&#8221;template&#8221;参数的名称不包含“.jelly”。
<ul>
<li><em>template</em> -模板名称，默认&#8221;html&#8221;。</li>
</ul>
</li>
<li><strong>${FILE, <em>path</em>} -</strong>包含一个指定文件的内容
<ul>
<li><em>path</em> -文件路径，注意，是工作区目录的相对路径。</li>
</ul>
</li>
<li><strong>${TEST_COUNTS, <em>var</em>} -</strong>显示测试的数量。
<ul>
<li><em>var</em> &#8211; 默认“total”。
<ul>
<li>total -所有测试的数量。</li>
<li>fail -失败测试的数量。</li>
<li>skip -跳过测试的数量。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>项目配置<strong></strong></h4>
<p>要想在一个项目中使用email-ext插件，你首先必须在项目配置页激活它。在&#8221;Post-build Actions&#8221;选项中勾选&#8221;Editable Email Notification&#8221;标签。</p>
<p style="text-align: center;"><a href="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_3.jpg"><img class="aligncenter size-full wp-image-598" style="border: 1px solid black;" title="hudson_email_ext_3" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_3.jpg" alt="" width="558" height="172" /></a></p>
<h5><strong>项目基本配置</strong><strong></strong></h5>
<p>当插件激活后你就能编辑如下三个字段：</p>
<ul>
<li><strong>Global Recipient List</strong> -这是一个以逗号(或者空格)分隔的可接受邮件的邮箱地址列表。允许您为每封邮件指定单独的列表。</li>
<li><strong>Default Subject</strong> -允许你配置令牌，这样就可以在项目中更容易地配置所有邮件的主题。</li>
<li><strong>Default Content</strong> -跟 Default Subject的作用一样，但是是把主题替换内容主体。</li>
</ul>
<h5><strong>项目高级配置</strong><strong></strong></h5>
<p>要查看插件的高级配置，请点击&#8221;Advanced&#8221;按钮。该选项允许您各种类型的邮件触发器指定接收者。默认情况下，唯一使用的触发器配置是&#8221;Failure&#8221;触发器。要增加更多的触发器，选择“Add a Trigger”旁边下拉列表中的类型，它会增加到控件上面的列表中。一旦你增加了一个触发器，你就可以对它做一些选择。如果你点击一个触发器旁边的”?”号，它将告诉你你在什么前置条件中来触发邮件发送。如下图。</p>
<p style="text-align: center;"><a href="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_4.jpg"><img class="aligncenter size-full wp-image-599" style="border: 1px solid black;" title="hudson_email_ext_4" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_4.jpg" alt="" width="558" height="162" /></a></p>
<ul>
<li><strong>Send to Recipient List</strong> -如果勾选，邮件将发送到&#8221;Global Recipient List&#8221;中的所有邮件地址。</li>
<li><strong>Send to Committers</strong> -该邮件会发给上次构建时检查过代码的人员，该插件会基于提交者的ID和追加Jenkins配置页面的(default email suffix)默认邮件后缀来生成一个邮件地址。譬如，上次提交代码的人是”first.last”， 默认的电子邮件后缀为“@somewhere.com”，那么电子邮件将被发送到“first.last@ somewhere.com”。</li>
<li><strong>Send To Requester</strong> -如果勾选，邮件将发送给构建触发者。</li>
<li><strong>Include Culprits</strong> -如果勾选，而且 “Send To Committers”勾选，邮件将包含最后成功构建的提交者。</li>
<li><strong>More Configuration</strong> -通过单击&#8221;+(expand)&#8221;链接您能为每个邮件触发器作更多单独的设置。
<ul>
<li><strong>Recipient List</strong> -这是一个以逗号(或者空格)分隔的可接受邮件的邮箱地址列表。如果触发就发送邮件到该列表。该列表会追加在&#8221;Global Recipient List&#8221;里。</li>
<li><strong>Subject</strong> &#8211; 指定选择邮件的主题。注意：高级选项中的邮件触发器类型可覆盖对它的配置。</li>
<li><strong>Content</strong> -指定选择邮件的内容主体。注意：高级选项中的邮件触发器类型可覆盖对它的配置。</li>
</ul>
</li>
<li><strong>Remove</strong> -通过单击指定触发器当前行的&#8221;Delete&#8221;按钮，你可以删除该触发器。</li>
</ul>
<h5><strong>项目邮件令牌</strong><strong></strong></h5>
<p>email-ext插件使用<strong>令牌</strong>来允许动态数据插入到邮件的主题和内容主体中。<strong>令牌</strong>是一个以$(美元符号)开始，并以空格结束的字符串。当一个邮件触发时，主题和内容主体字段的所有令牌都会通过真实的值动态地替换。同样，令牌中的“值”能包含其它的令牌，那将被替换成真实的内容。比如， $DEFAULT_SUBJECT令牌能通过从公共配置页面的Default Subject字段中的文本(或者其它令牌)替换。同理， $PROJECT_DEFAULT_SUBJECT令牌也能通过项目配置页面的Default Subject 字段中值替换。</p>
<p>一旦你的项目中激活email-ext插件，它会使用默认值设置邮件的内容字段。项目配置页的默认主题和主体内容字段分别对应的是DEFAULT_SUBJECT和DEFAULT_CONTENT，因此它会自动地使用全局的配置。同理，每个触发器中的内容分别对应的是$PROJECT_DEFAULT_SUBJECT 和 $PROJECT_DEFAULT_CONTENT，所以它也会自动地使用项目的配置。由于令牌中的“值”能包含其它的令牌，这样一来，您就能为令牌快速地创建不同的切入点：全局级别(所有项目)，专属级别(单一项目)，通用级别(两者之间)。</p>
<p>如果你要查看所有可用的令牌，你可以点击项目配置页的Content Token Reference的?号获取详细的信息。</p>
<p>根据帮助文档，我们可以了解到一些公共属性，下面我解释一下常用的属性。<br />
属性详解：</p>
<p>1、触发器类型<strong></strong></p>
<p>注意：所有的触发器都只能配置一次。</p>
<p><strong>Failure：</strong>即时发送构建失败的邮件。如果&#8221;Still Failing&#8221;触发器已配置，而上一次构建的状态是&#8221;Failure&#8221;，那么&#8221;Still Failing&#8221;触发器将发送一封邮件来替代(它)。<br />
<strong>Unstable：</strong>即时发送构建不稳固的邮件。如果&#8221;Still Unstable&#8221;触发器已配置，而上一次构建的状态是&#8221;Unstable&#8221;，那么&#8221;Still Unstable&#8221;触发器将发送一封邮件来替代(它)。<br />
<strong>Still Failing：</strong>如果两次或两次以上连续构建的状态为&#8221;Failure&#8221;，发送该邮件。<br />
<strong>Success：</strong>如果构建的状态为&#8221;Successful&#8221;发送邮件。如果&#8221;Fixed&#8221;已配置，而上次构建的状态为“Failure”或“Unstable”，那么&#8221;Fixed&#8221;触发器将发送一封邮件来替代(它)。<br />
<strong>Fixed：</strong>当构建状态从“Failure”或“Unstable”变为&#8221;Successful&#8221;时发送邮件。<br />
<strong>Still Unstabl</strong>e：如果两次或两次以上连续构建的状态为&#8221; Unstable &#8220;，发送该邮件。<br />
<strong>Before Build：</strong>当构建开始时发送邮件。</p>
<p>2、Content Token Reference[项目配置]</p>
<p>注意：这里只解释系统配置页面中缺少的令牌。</p>
<ul>
<li><strong>${DEFAULT_SUBJECT}      -</strong>这是Jenkins系统配置页面默认配置的邮件主题</li>
<li><strong>${DEFAULT_CONTENT}      -</strong>这是Jenkins系统配置页面默认配置的邮件内容主体</li>
<li><strong>${PROJECT_DEFAULT_SUBJECT}      &#8211; </strong>这是项目的默认邮件主题。高级配置中使用该令牌的结果要优先于Default Subject字段。警告：不要在Default Subject 或者Default Content中使用该令牌，它会产生一个未知的结果。</li>
<li><strong>${PROJECT_DEFAULT_CONTENT}      -</strong>这是项目的默认邮件内容主体。高级配置中使用该令牌的结果要优先于Default Content字段。警告：不要在Default Subject 或者Default Content中使用该令牌，它会产生一个未知的结果。</li>
</ul>
<h2><strong>Jelly </strong><strong>脚本</strong></h2>
<p>从Jenkins(Hudson)2.9版本开始我们可以使用Jelly脚本。Jelly脚本跟Hudson的API挂钩，能获得你想要的任何信息，所以它很强大。插件有两个打包后的Jelly脚本，当然你也可以自定义(脚本)。</p>
<p>关于插件中默认的两个Jelly脚本：一个用来设计HTML格式邮件，另一个则是定义TEXT格式邮件。通过上面的截图看到它们的样子。你能通过使用模板参数指定插件调用哪一个脚本。它们的使用方法如下：</p>
<ul>
<li>文本格式： ${JELLY_SCRIPT,template=&#8221;text&#8221;}</li>
<li>HTML格式:  ${JELLY_SCRIPT,template=&#8221;html&#8221;}</li>
</ul>
<p>你也能编写属于自己的Jelly脚本。Jelly脚本能跟Hudson的API(包括<a href="http://jenkins-ci.org/javadoc/hudson/model/AbstractBuild.html">hudson.model.AbstractBuild</a>和<a href="http://jenkins-ci.org/javadoc/hudson/model/AbstractProject.html">hudson.model.AbstractProject</a>)挂钩，因而特别强大。如果你打算这么做，你可以先参考现有的<a href="http://fisheye.jenkins-ci.org/browse/Hudson/trunk/hudson/plugins/email-ext/src/main/resources/hudson/plugins/emailext/templates/html.jelly?r=HEAD">html</a>和<a href="http://fisheye.jenkins-ci.org/browse/Hudson/trunk/hudson/plugins/email-ext/src/main/resources/hudson/plugins/emailext/templates/text.jelly?r=HEAD">text</a>脚本一探究竟。</p>
<p>值得注意的是，拥有Hudson管理员权限是使用自定义Jelly脚本(该脚本没有跟email-ext打包)的前提。脚本的生成步骤本身其实相对简单：</p>
<ol>
<li>创建Jelly脚本。脚本的名称应该是<em>&lt;</em><em>名称</em><em>&gt;.jelly</em>。名称以.jelly结尾是很重要的。</li>
<li>让你的Hudson管理员把脚本存放在<em>HUDSON_HOME\email-templates</em>文件夹里。</li>
<li>使用Jelly令牌，让template匹配你的脚本名称(不要包含后缀)。比如，脚本的名称为foobar.jelly，则邮件内容中应该是${JELLY_SCRIPT,template=&#8221;foobar&#8221;}。</li>
</ol>
<p>下面两个图就是就是使用Jelly脚本生成的邮件（最新版Email-ext新增html_gamil模板，它跟html模板类似，所以这里不再显示它的截图）：</p>
<p><img class="size-full wp-image-600 alignnone" style="margin-left: 10px; margin-right: 10px; border: 1px solid black;" title="hudson_email_ext_5" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_5.jpg" alt="" width="335" height="314" /><img class="size-full wp-image-601 alignnone" style="margin-top: 0px; margin-bottom: 0px; margin-left: 10px; margin-right: 10px; border: 1px solid black;" title="hudson_email_ext_6" src="http://www.juvenxu.com/wp-content/uploads/2011/05/hudson_email_ext_6.jpg" alt="" width="335" height="314" /></p>
<h2><strong>总结</strong><strong></strong></h2>
<p>以上就是我介绍的Email-ext插件，由于自己的局限，对于它的使用没有更深的了解。参考资料[2]中还有关于它的扩展，你也可以自行扩充它的功能。如果您有关于该插件以及Jenkins使用的更多更好的感受，我期待与您一起分享。</p>
<h2><strong>参考资料</strong><strong></strong></h2>
<p><em>[1] <a href="http://www.juvenxu.com/mvn-in-action/">《Maven实战》</a>第11章11.9邮件反馈。<strong></strong></em></p>
<p><em>[2] <a href="https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin">https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/05/18/hudson-email-ext/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>InfoQ Maven专栏（八）——常用Maven插件介绍（下）</title>
		<link>http://www.juvenxu.com/2011/05/11/infoq-maven-most-used-maven-plugins-b/</link>
		<comments>http://www.juvenxu.com/2011/05/11/infoq-maven-most-used-maven-plugins-b/#comments</comments>
		<pubDate>Wed, 11 May 2011 06:43:36 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[Maven]]></category>
		<category><![CDATA[InfoQ]]></category>
		<category><![CDATA[InfoQ Maven专栏]]></category>
		<category><![CDATA[maven插件]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=589</guid>
		<description><![CDATA[我们都知道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插件。 [...]]]></description>
			<content:encoded><![CDATA[<p>我们都知道Maven本质上是一个插件框架，它的核心并不执行任何具体的构建任务，所有这些任务都交给插件来完成，例如编译源代码是由maven- compiler-plugin完成的。进一步说，每个任务对应了一个插件目标（goal），每个插件会有一个或者多个目标，例如maven- compiler-plugin的compile目标用来编译位于<code>src/main/java/</code>目录下的主源码，testCompile目标用来编译位于<code>src/test/java/</code>目录下的测试源码。</p>
<p>用户可以通过两种方式调用Maven插件目标。第一种方式是将插件目标与生命周期阶段（lifecycle phase）绑定，这样用户在命令行只是输入生命周期阶段而已，例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定，因此命令<strong>mvn compile</strong>实际上是先定位到compile这一生命周期阶段，然后再根据绑定关系调用maven-compiler-plugin的compile目标。第二种方式是直接在命令行指定要执行的插件目标，例如<strong>mvn archetype:generate</strong> 就表示调用maven-archetype-plugin的generate目标，这种带冒号的调用方式与生命周期无关。</p>
<p>认识上述Maven插件的基本概念能帮助你理解Maven的工作机制，不过要想更高效率地使用Maven，了解一些常用的插件还是很有必要的，这可以帮助你避免一不小心重新发明轮子。多年来Maven社区积累了大量的经验，并随之形成了一个成熟的插件生态圈。Maven官方有两个插件列表，第一个列表的GroupId为org.apache.maven.plugins，这里的插件最为成熟，具体地址为：<a href="http://maven.apache.org/plugins/index.html">http://maven.apache.org/plugins/index.html</a>。第二个列表的GroupId为org.codehaus.mojo，这里的插件没有那么核心，但也有不少十分有用，其地址为：<a href="http://mojo.codehaus.org/plugins.html">http://mojo.codehaus.org/plugins.html</a>。</p>
<p>接下来笔者根据自己的经验介绍一些最常用的Maven插件，在不同的环境下它们各自都有其出色的表现，熟练地使用它们能让你的日常构建工作事半功倍。本文为下半部分。（上半部分内容参见<a href="http://www.juvenxu.com/2011/04/27/infoq-maven-most-used-maven-plugins-a/">InfoQ Maven专栏（七）——常用Maven插件介绍（上）</a>）</p>
<h2>maven-resources-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-resources-plugin/">http://maven.apache.org/plugins/maven-resources-plugin/</a></p>
<p>为了使项目结构更为清晰，Maven区别对待Java代码文件和资源文件，maven-compiler-plugin用来编译Java代码，maven-resources-plugin则用来处理资源文件。默认的主资源文件目录是<code>src/main/resources</code>，很多用户会需要添加额外的资源文件目录，这个时候就可以通过配置maven-resources-plugin来实现。此外，资源文件过滤也是Maven的一大特性，你可以在资源文件中使用<em>${propertyName}</em>形式的Maven属性，然后配置maven-resources-plugin开启对资源文件的过滤，之后就可以针对不同环境通过命令行或者Profile传入属性的值，以实现更为灵活的构建。</p>
<h2>maven-surefire-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-surefire-plugin/">http://maven.apache.org/plugins/maven-surefire-plugin/</a></p>
<p>可能是由于历史的原因，Maven 2/3中用于执行测试的插件不是maven-test-plugin，而是maven-surefire-plugin。其实大部分时间内，只要你的测试类遵循通用的命令约定（以Test结尾、以TestCase结尾、或者以Test开头），就几乎不用知晓该插件的存在。然而在当你想要跳过测试、排除某些测试类、或者使用一些TestNG特性的时候，了解maven-surefire-plugin的一些配置选项就很有用了。例如 <strong>mvn test -Dtest=FooTest</strong> 这样一条命令的效果是仅运行FooTest测试类，这是通过控制maven-surefire-plugin的test参数实现的。</p>
<h2>build-helper-maven-plugin</h2>
<p><a href="http://mojo.codehaus.org/build-helper-maven-plugin/">http://mojo.codehaus.org/build-helper-maven-plugin/</a></p>
<p>Maven默认只允许指定一个主Java代码目录和一个测试Java代码目录，虽然这其实是个应当尽量遵守的约定，但偶尔你还是会希望能够指定多个源码目录（例如为了应对遗留项目），build-helper-maven-plugin的add-source目标就是服务于这个目的，通常它被绑定到默认生命周期的generate-sources阶段以添加额外的源码目录。需要强调的是，这种做法还是不推荐的，因为它破坏了 Maven的约定，而且可能会遇到其他严格遵守约定的插件工具无法正确识别额外的源码目录。</p>
<p>build-helper-maven-plugin的另一个非常有用的目标是attach-artifact，使用该目标你可以以classifier的形式选取部分项目文件生成附属构件，并同时install到本地仓库，也可以deploy到远程仓库。</p>
<h2>exec-maven-plugin</h2>
<p><a href="http://mojo.codehaus.org/exec-maven-plugin/">http://mojo.codehaus.org/exec-maven-plugin/</a></p>
<p>exec-maven-plugin很好理解，顾名思义，它能让你运行任何本地的系统程序，在某些特定情况下，运行一个Maven外部的程序可能就是最简单的问题解决方案，这就是<strong>exec:exec</strong>的用途，当然，该插件还允许你配置相关的程序运行参数。除了exec目标之外，exec-maven-plugin还提供了一个java目标，该目标要求你提供一个mainClass参数，然后它能够利用当前项目的依赖作为classpath，在同一个JVM中运行该mainClass。有时候，为了简单的演示一个命令行Java程序，你可以在POM中配置好exec-maven-plugin的相关运行参数，然后直接在命令运行 <strong>mvn exec:java</strong> 以查看运行效果。</p>
<h2>jetty-maven-plugin</h2>
<p><a href="http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin">http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin</a></p>
<p>在进行Web开发的时候，打开浏览器对应用进行手动的测试几乎是无法避免的，这种测试方法通常就是将项目打包成war文件，然后部署到Web容器中，再启动容器进行验证，这显然十分耗时。为了帮助开发者节省时间，jetty-maven-plugin应运而生，它完全兼容 Maven项目的目录结构，能够周期性地检查源文件，一旦发现变更后自动更新到内置的Jetty Web容器中。做一些基本配置后（例如Web应用的contextPath和自动扫描变更的时间间隔），你只要执行 <strong>mvn jetty:run</strong> ，然后在IDE中修改代码，代码经IDE自动编译后产生变更，再由jetty-maven-plugin侦测到后更新至Jetty容器，这时你就可以直接测试Web页面了。需要注意的是，jetty-maven-plugin并不是宿主于Apache或Codehaus的官方插件，因此使用的时候需要额外的配置<code>settings.xml</code>的pluginGroups元素，将org.mortbay.jetty这个pluginGroup加入。</p>
<h2>versions-maven-plugin</h2>
<p><a href="http://mojo.codehaus.org/versions-maven-plugin/">http://mojo.codehaus.org/versions-maven-plugin/</a></p>
<p>很多Maven用户遇到过这样一个问题，当项目包含大量模块的时候，为他们集体更新版本就变成一件烦人的事情，到底有没有自动化工具能帮助完成这件事情呢？（当然你可以使用sed之类的文本操作工具，不过不在本文讨论范围）答案是肯定的，versions-maven- plugin提供了很多目标帮助你管理Maven项目的各种版本信息。例如最常用的，命令 <strong>mvn versions:set -DnewVersion=1.1-SNAPSHOT</strong> 就能帮助你把所有模块的版本更新到1.1-SNAPSHOT。该插件还提供了其他一些很有用的目标，display-dependency- updates能告诉你项目依赖有哪些可用的更新；类似的display-plugin-updates能告诉你可用的插件更新；然后use- latest-versions能自动帮你将所有依赖升级到最新版本。最后，如果你对所做的更改满意，则可以使用 <strong>mvn versions:commit</strong> 提交，不满意的话也可以使用 <strong>mvn versions:revert</strong> 进行撤销。</p>
<h2>小结</h2>
<p>本文介绍了一些最常用的Maven插件，这里指的“常用”是指经常需要进行配置的插件，事实上我们用Maven的时候很多其它插件也是必须的，例如默认的编译插件maven-compiler-plugin和默认的打包插件maven-jar-plugin，但因为很少需要对它们进行配置，因此不在本文讨论范围。了解常用的Maven插件能帮助你事倍功半地完成项目构建任务，反之你就可能会因为经常遇到一些难以解决的问题而感到沮丧。本文介绍的插件基本能覆盖大部分Maven用户的日常使用需要，如果你真有非常特殊的需求，自行编写一个Maven插件也不是难事，更何况还有这么多开放源代码的插件供你参考。</p>
<p>本文的这个插件列表并不是一个完整列表，读者有兴趣的话也可以去仔细浏览一下Apache和Codehaus Mojo的Maven插件列表，以的到一个更为全面的认识。最后，在线的Maven仓库搜索引擎如<a href="http://search.maven.org/">http://search.maven.org/</a>也能帮助你快速找到自己感兴趣的Maven插件。</p>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>，版权所有，<em>原文为</em><a href="http://www.infoq.com/cn/news/2011/05/xxb-maven-8-plugin">《Maven实战（八）——常用Maven插件介绍（下）》</a></em><em><em>，</em>如需转载，请务必附带本声明，谢谢。<br />
<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>是一个面向中高端技术人员的在线独立社区，为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如<a href="http://www.qconbeijing.com/" target="_blank">QCon</a> 、线下技术交流活动<a title="QClub" href="http://www.infoq.com/cn/qclub" target="_blank">QClub</a>、免费迷你书下载如<a title="《架构师 》" href="http://www.infoq.com/cn/architect" target="_blank">《</a><a href="http://www.infoq.com/cn/architect" target="_blank">架构师</a>》等。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/05/11/infoq-maven-most-used-maven-plugins-b/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>InfoQ Maven专栏（七）——常用Maven插件介绍（上）</title>
		<link>http://www.juvenxu.com/2011/04/27/infoq-maven-most-used-maven-plugins-a/</link>
		<comments>http://www.juvenxu.com/2011/04/27/infoq-maven-most-used-maven-plugins-a/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 08:00:12 +0000</pubDate>
		<dc:creator>juvenxu</dc:creator>
				<category><![CDATA[Maven]]></category>
		<category><![CDATA[InfoQ]]></category>
		<category><![CDATA[InfoQ Maven专栏]]></category>
		<category><![CDATA[maven插件]]></category>

		<guid isPermaLink="false">http://www.juvenxu.com/?p=584</guid>
		<description><![CDATA[我们都知道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-antrun-plugin http://maven.apache.org/plugins/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 http://maven.apache.org/plugins/maven-assembly-plugin/ maven-assembly-plugin的用途是制作项目分发包，该分发包可能包含了项目的可执行文件、源代码、readme、平台脚本等等。maven-assembly-plugin支持各种主流的格式如zip、tar.gz、jar和war等，具体打包哪些文件是高度可控的，例如用户可以按文件级别的粒度、文件集级别的粒度、模块级别的粒度、以及依赖级别的粒度控制打包，此外，包含和排除配置也是支持的。maven-assembly-plugin要求用户使用一个名为assembly.xml的元数据文件来表述打包，它的single目标可以直接在命令行调用，也可以被绑定至生命周期。 maven-dependency-plugin http://maven.apache.org/plugins/maven-dependency-plugin/ maven-dependency-plugin最大的用途是帮助分析项目依赖，dependency:list能够列出项目最终解析到的依赖列表，dependency:tree能进一步的描绘项目依赖树，dependency:analyze可以告诉你项目依赖潜在的问题，如果你有直接使用到的却未声明的依赖，该目标就会发出警告。maven-dependency-plugin还有很多目标帮助你操作依赖文件，例如dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。 maven-enforcer-plugin http://maven.apache.org/plugins/maven-enforcer-plugin/ 在一个稍大一点的组织或团队中，你无法保证所有成员都熟悉Maven，那他们做一些比较愚蠢的事情就会变得很正常，例如给项目引入了外部的SNAPSHOT依赖而导致构建不稳定，使用了一个与大家不一致的Maven版本而经常抱怨构建出现诡异问题。maven-enforcer-plugin能够帮助你避免之类问题，它允许你创建一系列规则强制大家遵守，包括设定Java版本、设定Maven版本、禁止某些依赖、禁止SNAPSHOT依赖。只要在一个父POM配置规则，然后让大家继承，当规则遭到破坏的时候，Maven就会报错。除了标准的规则之外，你还可以扩展该插件，编写自己的规则。maven-enforcer-plugin的enforce目标负责检查规则，它默认绑定到生命周期的validate阶段。 maven-help-plugin http://maven.apache.org/plugins/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 http://maven.apache.org/plugins/maven-release-plugin/ maven-release-plugin的用途是帮助自动化项目版本发布，它依赖于POM中的SCM信息。release:prepare用来准备版本发布，具体的工作包括检查是否有未提交代码、检查是否有SNAPSHOT依赖、升级项目的SNAPSHOT版本至RELEASE版本、为项目打标签等等。release:perform则是签出标签中的RELEASE源码，构建并发布。版本发布是非常琐碎的工作，它涉及了各种检查，而且由于该工作仅仅是偶尔需要，因此手动操作很容易遗漏一些细节，maven-release-plugin让该工作变得非常快速简便，不易出错。maven-release-plugin的各种目标通常直接在命令行调用，因为版本发布显然不是日常构建生命周期的一部分。 本文已经首发于InfoQ中文站，版权所有，原文为《Maven实战（七）——常用Maven插件介绍（上）》，如需转载，请务必附带本声明，谢谢。 InfoQ中文站是一个面向中高端技术人员的在线独立社区，为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如《架构师》等。]]></description>
			<content:encoded><![CDATA[<p>我们都知道Maven本质上是一个插件框架，它的核心并不执行任何具体的构建任务，所有这些任务都交给插件来完成，例如编译源代码是由maven-compiler-plugin完成的。进一步说，每个任务对应了一个插件目标（goal），每个插件会有一个或者多个目标，例如maven-compiler-plugin的compile目标用来编译位于<code>src/main/java/</code>目录下的主源码，testCompile目标用来编译位于<code>src/test/java/</code>目录下的测试源码。</p>
<p>用户可以通过两种方式调用Maven插件目标。第一种方式是将插件目标与生命周期阶段（lifecycle phase）绑定，这样用户在命令行只是输入生命周期阶段而已，例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定，因此命令<strong>mvn compile</strong>实际上是先定位到compile这一生命周期阶段，然后再根据绑定关系调用maven-compiler-plugin的compile目标。第二种方式是直接在命令行指定要执行的插件目标，例如<strong>mvn archetype:generate</strong> 就表示调用maven-archetype-plugin的generate目标，这种带冒号的调用方式与生命周期无关。</p>
<p>认识上述Maven插件的基本概念能帮助你理解Maven的工作机制，不过要想更高效率地使用Maven，了解一些常用的插件还是很有必要的，这可以帮助你避免一不小心重新发明轮子。多年来Maven社区积累了大量的经验，并随之形成了一个成熟的插件生态圈。Maven官方有两个插件列表，第一个列表的GroupId为org.apache.maven.plugins，这里的插件最为成熟，具体地址为：<a href="http://maven.apache.org/plugins/index.html">http://maven.apache.org/plugins/index.html</a>。第二个列表的GroupId为org.codehaus.mojo，这里的插件没有那么核心，但也有不少十分有用，其地址为：<a href="http://mojo.codehaus.org/plugins.html">http://mojo.codehaus.org/plugins.html</a>。</p>
<p>接下来笔者根据自己的经验介绍一些最常用的Maven插件，在不同的环境下它们各自都有其出色的表现，熟练地使用它们能让你的日常构建工作事半功倍。</p>
<h2><a name="d0e724"></a>maven-antrun-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-antrun-plugin/">http://maven.apache.org/plugins/maven-antrun-plugin/</a></p>
<p>maven-antrun-plugin能让用户在Maven项目中运行Ant任务。用户可以直接在该插件的配置以Ant的方式编写Target，然后交给该插件的run目标去执行。在一些由Ant往Maven迁移的项目中，该插件尤其有用。此外当你发现需要编写一些自定义程度很高的任务，同时又觉得Maven不够灵活时，也可以以Ant的方式实现之。maven-antrun-plugin的run目标通常与生命周期绑定运行。</p>
<h2><a name="d0e732"></a>maven-archetype-plugin</h2>
<p><a href="http://maven.apache.org/archetype/maven-archetype-plugin/">http://maven.apache.org/archetype/maven-archetype-plugin/</a></p>
<p>Archtype指项目的骨架，Maven初学者最开始执行的Maven命令可能就是<strong>mvn archetype:generate</strong>，这实际上就是让maven-archetype-plugin生成一个很简单的项目骨架，帮助开发者快速上手。可能也有人看到一些文档写了<strong>mvn archetype:create</strong>，但实际上create目标已经被弃用了，取而代之的是generate目标，该目标使用交互式的方式提示用户输入必要的信息以创建项目，体验更好。maven-archetype-plugin还有一些其他目标帮助用户自己定义项目原型，例如你由一个产品需要交付给很多客户进行二次开发，你就可以为他们提供一个Archtype，帮助他们快速上手。</p>
<h2><a name="d0e746"></a>maven-assembly-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-assembly-plugin/">http://maven.apache.org/plugins/maven-assembly-plugin/</a></p>
<p>maven-assembly-plugin的用途是制作项目分发包，该分发包可能包含了项目的可执行文件、源代码、readme、平台脚本等等。maven-assembly-plugin支持各种主流的格式如zip、tar.gz、jar和war等，具体打包哪些文件是高度可控的，例如用户可以按文件级别的粒度、文件集级别的粒度、模块级别的粒度、以及依赖级别的粒度控制打包，此外，包含和排除配置也是支持的。maven-assembly-plugin要求用户使用一个名为<code>assembly.xml</code>的元数据文件来表述打包，它的single目标可以直接在命令行调用，也可以被绑定至生命周期。</p>
<h2><a name="d0e757"></a>maven-dependency-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-dependency-plugin/">http://maven.apache.org/plugins/maven-dependency-plugin/</a></p>
<p>maven-dependency-plugin最大的用途是帮助分析项目依赖，<strong>dependency:list</strong>能够列出项目最终解析到的依赖列表，<strong>dependency:tree</strong>能进一步的描绘项目依赖树，<strong>dependency:analyze</strong>可以告诉你项目依赖潜在的问题，如果你有直接使用到的却未声明的依赖，该目标就会发出警告。maven-dependency-plugin还有很多目标帮助你操作依赖文件，例如<strong>dependency:copy-dependencies</strong>能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。</p>
<h2><a name="d0e777"></a>maven-enforcer-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-enforcer-plugin/">http://maven.apache.org/plugins/maven-enforcer-plugin/</a></p>
<p>在一个稍大一点的组织或团队中，你无法保证所有成员都熟悉Maven，那他们做一些比较愚蠢的事情就会变得很正常，例如给项目引入了外部的SNAPSHOT依赖而导致构建不稳定，使用了一个与大家不一致的Maven版本而经常抱怨构建出现诡异问题。maven-enforcer-plugin能够帮助你避免之类问题，它允许你创建一系列规则强制大家遵守，包括设定Java版本、设定Maven版本、禁止某些依赖、禁止SNAPSHOT依赖。只要在一个父POM配置规则，然后让大家继承，当规则遭到破坏的时候，Maven就会报错。除了标准的规则之外，你还可以扩展该插件，编写自己的规则。maven-enforcer-plugin的enforce目标负责检查规则，它默认绑定到生命周期的validate阶段。</p>
<h2><a name="d0e785"></a>maven-help-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-help-plugin/">http://maven.apache.org/plugins/maven-help-plugin/</a></p>
<p>maven-help-plugin是一个小巧的辅助工具，最简单的<strong>help:system</strong>可以打印所有可用的环境变量和Java系统属性。<strong>help:effective-pom</strong>和<strong>help:effective-settings</strong>最为有用，它们分别打印项目的有效POM和有效settings，有效POM是指合并了所有父POM（包括Super POM）后的XML，当你不确定POM的某些信息从何而来时，就可以查看有效POM。有效settings同理，特别是当你发现自己配置的settings.xml没有生效时，就可以用<strong>help:effective-settings</strong>来验证。此外，maven-help-plugin的describe目标可以帮助你描述任何一个Maven插件的信息，还有all-profiles目标和active-profiles目标帮助查看项目的Profile。</p>
<h2><a name="d0e805"></a>maven-release-plugin</h2>
<p><a href="http://maven.apache.org/plugins/maven-release-plugin/">http://maven.apache.org/plugins/maven-release-plugin/</a></p>
<p>maven-release-plugin的用途是帮助自动化项目版本发布，它依赖于POM中的SCM信息。<strong>release:prepare</strong>用来准备版本发布，具体的工作包括检查是否有未提交代码、检查是否有SNAPSHOT依赖、升级项目的SNAPSHOT版本至RELEASE版本、为项目打标签等等。<strong>release:perform</strong>则是签出标签中的RELEASE源码，构建并发布。版本发布是非常琐碎的工作，它涉及了各种检查，而且由于该工作仅仅是偶尔需要，因此手动操作很容易遗漏一些细节，maven-release-plugin让该工作变得非常快速简便，不易出错。maven-release-plugin的各种目标通常直接在命令行调用，因为版本发布显然不是日常构建生命周期的一部分。</p>
<p><span style="color: #0000ff;"><em>本文已经首发于<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>，版权所有，<em>原文为</em><a href="http://www.infoq.com/cn/news/2011/04/xxb-maven-7-plugin">《Maven实战（七）——常用Maven插件介绍（上）》</a></em><em><em>，</em>如需转载，请务必附带本声明，谢谢。<br />
<a href="http://www.infoq.com/cn" target="_blank">InfoQ中文站</a>是一个面向中高端技术人员的在线独立社区，为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如<a href="http://www.qconbeijing.com/" target="_blank">QCon</a> 、线下技术交流活动<a title="QClub" href="http://www.infoq.com/cn/qclub" target="_blank">QClub</a>、免费迷你书下载如<a title="《架构师 》" href="http://www.infoq.com/cn/architect" target="_blank">《</a><a href="http://www.infoq.com/cn/architect" target="_blank">架构师</a>》等。</em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juvenxu.com/2011/04/27/infoq-maven-most-used-maven-plugins-a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

