这是本人首次翻译文章,兼之水平有限,有不当之处请多多包含。欢迎大家的批评和指正。另外,只是翻译了原文部分内容,请大家谅解。
蚂蚁怒了(Ant in Anger)(节选)
在项目开发中使用Apache Ant
Steve Loughran 著
介绍
Apache Ant 在团队项目开发可以成为价值无可估量的工具,而它也可能成为已经遇到危机的项目开发的另一个麻烦的根源。这篇文档包含了一些能够发挥Ant威力的措施和策略。在有些部分进行了适当的简化,而且几乎省略了全部Ant XML 文件的实例。
核心实践
澄清你想让Ant做什么
Ant不是银弹,它只不过是你可用的软件开发工具兵工厂里的另一颗生锈的子弹而已。它的最初目的是加速java项目的构建和发布。你当然可以扩展Ant 去做任何java使之可能的事情:比如说很容易想象去写一个图像处理任务来帮助网址来压缩和解压JPEG图像文件。但是这也使得Ant 真正的目的变得模糊,所以请仔细的考虑一下。
Ant也是集成开发环境的重要补充。一种事无巨细的发布管理以及清洁,自动化的构建的方法。但好的现代集成开发环境在其所属领域是生产率工具,一种你可以考虑一直使用的工具。Ant只是让你给团队在选择集成开发环境以更多的自由——“你可以使用任何工具开发,但是请使用Ant进行构建。”现在很多现代开源和商业集成开发环境都包括了Ant支持。开发者可以使用一种功能强大的开发环境,然后使用集成的Ant来提供一种严格的轻便的构建过程。
定义标准目标
当你有多个子工程时,定义一套标准目标。拥有接口和实现的jar文件的工程可以考虑impl和intf目标——为此调试版本使用单独的debug-impl 和debug-intf目标。当然,还有到处都需要的clean目标。
使用标准的目标名,很容易构建包含其中的Ant构建文件,这些文件使用Ant任务将工程构建成类文件。例如,clean目标可以从父目录传递下来intf和impl子目录。
<target name="clean" depends="clean-intf, clean-impl">
</target>
<target name="clean-intf" >
<ant dir="intf" target="clean" />
</target>
<target name="clean-impl">
<ant dir="impl" target="clean" />
</target>
如果你赋予目标以描述标记,然后运行ant –projecthelp将会列出所有的具有’main targets’描述符的任务,以及所以没有子目标描述符的任务。给你的所有的入口点以描述标记时非常有用的,尤其是在项目变得庞大和复杂之前。
通过新任务扩展Ant
如果Ant不能做你想要的东西,你可以使用exec和java任务或者内联脚本(inline scripting)来扩展它。在一个有很大build.xml文件的工程里,你很快就将发现在单一主要的地方实现功能会使维护费用降低。使用java代码来实现任务扩展一开始好像增加了额外的负担,但是却有额外的好处:
l 不需要改变任何build.xml文件就可以随后实现跨平台支持
l 代码可以被Ant工程自身提交,供其他人使用和维护
l 这使构建文件更简单
在某种程度上,来自于使用的声明-“构建文件”的功能退耦-“任务”,有助于Ant成功。如果你在Make或IDE中有一些复杂的事情要做的话,那么你就需要大量的每个人都恐惧的makefile文件,或者IDE配置文件,而这些文件总是非常脆弱的。但是Ant任务却是所有Ant用户都可以复用和共享的。许多现在的Ant核心和可选的任务,还有你现在做的和即将扩展的任务,都可以使用那些人们在解决他们自己的问题时所写的东西。
拥抱自动化测试
Ant可以使你唤起JUnit任务,这样就可以单元测试你们团队的代码。自动化测试看起来像是额外的负担,但是JUnit使得单元测试非常之简单,你没有理由不做。花费一些时间在学习如何使用JUnit,写测试案例,和集成到Ant的测试目标,这样你的每日或每时构建就可以应用自动化测试了。
如果你想增加一种从供应链系统中获取代码的方法,那你或者通过一些Shell脚本或批处理文件将其作为Ant任务, 或者通过一些持续的集成工具。集成测试代码可以是纯的Ant任务,可运行在任何属于此任务的测试盒中。这种验证构建和单元测试能否从一般开发者的机器工作在不同的目标是很理想的。比如,在Win95/Java1.1环境下也可以被使用,尽管在有选择的情况下,没有开发者愿意使用这种配置。
自动化的系统测试要比单元测试难,但是如果你可以写java代码来加强你的系统的大部分——即使这些代码不能像JUnit任务那样运行——这样java任务就可以被用来调用他们。你最好指明你想使用一个新的java虚拟机来测试,这样一个重大的破坏就不会毁掉全部的构建。Junit的扩充,像HttpUnit用来测试web页,Cactus测试J2EE和Servlet,来帮助扩展测试框架。为了正确的测试,你还需要付出大量的努力以使这些工具和你的工程协同工作,并且从大单元,系统和衰退测试派生——但是你的客户会因为你让软件这样工作而喜欢你的。
学会使用和喜欢Ant的附加软件
Ant的分发版本不是Ant世界的极限,这仅仅只是个开始。看一下“扩展工具和任务页”作为扩展清单,这里是其中的一些。
l Checkstyle
这个工具审查你的代码,产生任何样式被破坏地点的HTML报告。没什么能够隐瞒这个代码警察的!提示:越早开始使用它,你的改正就越少。
l Ant-contrib
这个sourcefourge项目包括可以从核心的Ant中把那种意识形态的纯度分离出去的帮助任务;特别是foreach和trycatch任务。这能给你反复和额外的错误处理。而且在网上有<cc>任务组,能够在各种平台下编译链接本地代码。
l XDoclet
XDoclet给java增加了面向规划的属性。通过在代码中增加javadoc标记,你可以使用XDoclet自动产生web.xml描述文件,taglib描述符,EJB接口,JMX接口类,XML/SQL绑定的映射,以及更多。这里的关键是所有的高精确的小xml文件你需要去创建的,EJB和JMX接口你需要去实现的,都可以通过在java代码中加一些帮助属性来自动产生。这减少了错误,意味着你可以改变你的代码,让应用程序的其他部分从源代码得到提示。没有它,永远不要作EJB,JMX和web应用程序!
Ant跨平台
Ant是迄今为止跨平台的java开发和测试的最好的基础。但是如果你不是很注意的话,很可能就产生了只能在一种平台——或者甚至是一台工作站上工作的构建文件。
跨平台的Ant使用的主要障碍是命令行工具(exec任务)的使用不是可移植的,路径相关的,而且在事件的位置很难译码的。
命令行应用:Exec/Apply
使用外部调用的麻烦是并不是所有的功能都能跨平台的,而且它们有着不同的名字——DOS系统总是期望.ext和.bat作为文件尾。如果你明确的在命令名中包含这些扩展,这将是很糟的,但是当它允许不在名称抵触发生就在项目的同一个二进制目录保持了unix和Dos的可执行版本,这是很美妙的。
这两种命令行调用任务都需要你指明你想要你的代码运行在何种平台下,所以你可以为你打算使用的每种平台写不同的任务。可选择地,平台的不同可以在Ant调用的扩展代码中解决。这就是一些在新的任务或者外围的脚本文件编译过的java文件。
路径跨平台
Unix路径使用前斜杠(/)分割目录,冒号分割条目。这样"/bin/java/lib/xerces.jar:/bin/java/lib/ant.jar"就是Unix中的路径。在Windows中路径必须使用分号,用来表明盘符的冒号,和后斜线(\)。比如"c:\bin\java\lib\xerces.jar;c:\bin\java\lib\ant.jar"。
这个平台间的不同造成了很多许多麻烦。
Ant减少了这种路径的难题,但是却没有根本消除它们。你自己也需要作一些工作。解决路径命名的规则就是分别解决DOS系的路径名和Unix系的路径名。磁盘名“C:”可以在DOS系中解决,但是把他们放在build.xml中就使所有可移植性破产。相关的文件路径更具可移植性。分号作为条目分割符——如果你的Ant调用包括一系列的为命令行中定义的属性的jar文件,那么分号是非常有用的。在构建文件中你最好建一个classpath,列出单独的文件(使用location=attributes),或者在classpath定义中包括一个*.jar文件集。
PathConvert任务可以将所有相关的路径转换为一个属性。为什么要这么作呢?因为这样你就可以通过其它方式使用路径——比如说将其作为参数传递给你调用的应用,或者使用替换任务将其修补进局部化的shell脚本或者批处理文件。
注意DOS系的文件系统是大小写不敏感的,而且Windows表面上的4个或更多的字符的后缀,实际上也是3个字符(请试试在你的java目录下使用 DELETE *.jav,你就可以看到灾难性的后果)。
Ant的策略是大小写敏感,而不管那种文件系统,在后缀名的处理上是搜索*.jav文件时不会去找任何的.java文件。Java编译器当然也是大小写敏感的——你不能在"examplethree.java"中实现'ExampleThree'类。
一些任务只会执行在一种平台上——Chmod就是一个典型的例子。这些任务在不受支持的平台下经常导致仅仅是警告——其他目标的任务仍然会被调用。其他的任务在平台或者java版本上退化了它们的功能。特别地,那些调整文件时间印的任务在java1.1下就可能不正常工作。比如说能够这样做的Get,Touch和Unjar/Unwar/Unzip任务,在java1.1下退化功能,经常只能求助于当前的时间印。
最后,Perl不需要一系列的文件就可以很好的使java调用跨平台工作。大多数Unix分发包中都包含Perl,也很容易从ActiveState下载到它的Win32版本。带有.pl扩展名的Perl文件,第一行带有一般Unix路径的注释,被标记为可运行的,可以在Windows, OS/2和Unix上运行,这样就可以从Ant无需修改之间调用。Perl代码也可以用来解决它自身的跨平台问题。不要忘了当你重新发布Perl代码的时候在文件每行设置结束符以适应平台。<fixCRLF>可以为你作这些。