进一步了解Ant(作者: Michel Casabianca)

来源:互联网 发布:淘宝店装修代码生成器 编辑:程序博客网 时间:2024/05/17 01:58

本文是一个用于构建和部署Java工程的极具价值的工具(Ant)系列文章的第二部分。

在我的第一篇文章《Ant简介》(Oracle杂志,2002年11/12月号)中,我介绍了在Java开发过程中可能要执行的一些基本任务。我使用Ant自动编译Java源代码、创建JAR文件、运行程序并生成Javadoc。在这第二篇文章中,我将要讨论Ant的两个任务包(核心任务包和可选任务包)中的一些更高级的Ant特性。核心包包括构建、打包和部署Java工程的任务,也包括执行SQL语句的任务和与并发版本控制系统(Concurrent Versions System ,CVS)相集成的任务。可选包以各种方式扩展了Ant的功能,这些方式包括:与其他源代码控制系统相集成、运行unit测试和预编译JavaServer Pages (JSP)等。我还将讨论它与Oracle9i JDeveloper 9.0.3的集成,并提供一些有用的Ant提示与技巧。

打包一个应用程序

为了分布应用程序,你可能需要生成一个文档库:tar.gz 和/或zip文件(分别用于UNIX 和Windows平台)。为了生成这两个文件,你应该编写清单1中所示的目标(target)。

在这个目标中,我使用两个专门任务来生成tar和zip文件。它们是非常类似的;它们的根元素包括一个说明要生成的的文档库名称的属性(属性tarfile和zipfile),它们都嵌套了一个专门的fileset来列举要包括在这个文档库中的文件。

这个目标看起来似乎是冗长的,但这有助于解决两个令人头疼的问题:文件许可和安装目录。当对一个文档库进行解压缩时,假定文件有合理的文件许可并将其安装到它们自己的目录中。

为了解决文件许可问题,我把要集成到该文档库中的文件按照功能分为两组:一个为不可执行的文件定义一个模式的patternset(指定的dist-non-exec),和将执行文件(外壳脚本和.bat文件)集中到bin目录中的另一个patternset(指定的dist-exec)。tarfileset--用于tar任务的专门fileset,使用mode属性管理文件许可,其值是该集合中文件的数字文件许可值。

为了解决安装目录问题,我使用tarfileset 和zipfileset的prefix属性。prefix值将被附加在该文档库的文件路径之前。这样,如果我写prefix="${name}"的话,该文档库的所有文件和目录将被包括在名称为该工程名的根目录下。因此,当解压缩时,生成的文档库将把这些文件安装在它们自己的目录下。

用JUnit运行unit测试

buildfile是一个运行unit测试的合适地方。编写unit测试是为了尽早地发现问题,并对代码进行修改。Junit是一个用于在Java工程内开发unit测试的测试框架。包括在Ant 可选包中的junit任务使你能够从Ant buildfile执行这些测试。这样,使用junit任务,你就能够在每次创建或部署Java工程时,轻松地运行所有的unit测试。下面的例子说明了如何使用junit任务:

<target name="test"         description="Run JUnit tests">   <junit haltonfailure="true"          printsummary="withOutAndErr">     <classpath>        <fileset dir="${lib}"                  includes="**/*.jar"/>     </classpath>     <batchtest>        <fileset dir="${src}" includes="**/*Test.java"/>      </batchtest>   </junit></target>

如果一个测试失败,haltonfailure="true"属性要求Ant停止;printsummary= "withOutAndErr"属性在控制台上打印该测试的标准和错误输出(当开发测试时,它是有用的)。classpath属性定义运行该测试的CLASSPATH;CLASSPATH必须包括JUnit JAR文件,它也必须被显示在Ant安装的lib目录中。batchtest元素定义测试文件以运行(其类名称以Test结尾)。

发出SQL命令

Ant提供sql任务以执行简单的SQL语句和包含多个SQL语句的脚本文件。sql任务能够用于根据任意数据源运行SQL语句,你拥有这些数据源的符合Java数据库连接API (JDBC)的驱动程序。这里给出了一个连接到Oracle数据库并对表test进行撤销、创建和插入操作的例子:

<target name="sql">  <sql driver="oracle.jdbc.driver.OracleDriver"      url="jdbc:oracle:thin:@foo:1521:BAR"      userid="scott"      password="tiger">    DROP TABLE TEST;      CREATE TABLE TEST (     ID INTEGER,     NAME VARCHAR(20),    );      INSERT INTO TEST VALUES(1,'Jeff');    INSERT INTO TEST VALUES(2,'Rob');    INSERT INTO TEST VALUES(3,'Michel');  </sql></target>

在这个例子中,sql任务使用由driver属性指定的驱动程序连接到在url属性中指定的数据库。你必须在Ant安装的lib目录中为数据库安装JDBC驱动程序库。建立连接以后,所包含的SQL语句被执行。

在你想要从Ant buildfile 内执行数量有限的SQL语句的情况下,这种sql任务类型是极为有用的。然而,你可以想像一下有大量SQL语句的场景,例如重建数据库索引。在这种情况下,执行一个外部SQL文件、而不是将全部的SQL 命令序列包含在你的Ant buildfile中是较为容易的。你可以使用fileset类型来指定一个或多个SQL脚本文件,它们包含你想要执行的任意数量的SQL语句。下面的例子将对其进行说明:

<target name="sql">  <sql driver="oracle.jdbc.driver.OracleDriver"       url="jdbc:oracle:thin:@foo:1521:BAR"       userid="scott"        password="tiger">     <fileset dir="/opt/build/foobar/sql">        <include name="rebuild_indices.sql"/>      </fileset>  </sql></target>

在这个例子中,fileset类型指定目录/opt/ build/foobar/sql,include类型在那个目录中指定rebuild_indices.sql文件以执行。fileset类型允许你将外部SQL代码与你的Ant buildfile隔离开来,这样便能够简化对Ant buildfile和SQL脚本的维护。

在使用Ant时,你可能会遇到这样的情况:SQL语句包括诸如左箭头键或&号(<和&)等XML字符。buildfile使用XML语法,这样Ant将试图作为XML来解释这些字符,从而导致SQL语句失败。为了解决这个问题,你可以将你的SQL代码放到一个CDATA块中,如下所示:

<target name="sql">  <sql driver="oracle.jdbc.driver.OracleDriver"       url="jdbc:oracle:thin:@foo:1521:BAR"       userid="scott"       password="tiger">   <![CDATA[     update some_table set column1 = column1 + 1         where column2 < 42;    ]]>  </sql></target>

在这个例子中,CDATA块包含一个在其WHERE字句中包括左箭头键(<)的SQL语句。为了避免Ant的 XML解析器将其解释为一个XML标记的开始,我将该语句嵌入到了CDATA块中。

集成到源代码控制系统

Ant提供了用于执行基本的源代码控制操作(例如,登记(check in)、检查(check out)和标注代码等)的任务。Ant现在支持以下的源代码控制系统:Clearcase、Continuous/Synergy、CVS、Perforce、PVCS、StarTeam和Visual SourceSafe。对除了CVS之外的所有系统的支持可从可选任务包中获取。注意,为了与除CVS之外的源代码控制系统集成,Ant可能需要访问附加的库。例如,为了使 StarTeam和Ant协同工作,必须将starteam-sdk.jar文件放置在Ant安装的lib目录中。

为了检查和创建Ant的最新开发版本,运行清单2中所示的buildfile。如果这个文件的build目标创建Ant失败的话,试着创建ORO工程。将属性模块的值改为jakarta-oro。

buildfile使用cvs任务检查该工程(在checkout目标中)和ant任务,以便使用Ant(在build目标中)构建它。cvs任务必须使用位于用户主目录下的 .cvspass文件中的数据在CVS服务器上进行验证。清单2 buildfile中的.cvspass文件可能是空的,因为CVS信息库是可以公共访问的。

login目标使用cvspass任务写该信息库的cvsroot和密码以便在 .cvspass文件中访问它。出于安全性方面的考虑,你不应该在buildfile中对你的密码进行硬编码,而是应该通过命令行将它传递到脚本,用命令行ant -Dcvsroot=foo -Dpassword=bar login启动Ant。

使用诸如清单2中的buildfile,你可以轻松地将工程分发给开发人员,这对于欢迎任何开发人员参与的开放源码的工程来说是极为重要的。但是这一方法也是在常规基础上使工程的提取和构建自动化的一种方式。

执行JSP预编译

当你在构建和编译Java源文件遇到一个错误时,javac能够通知你这个错误。这样你便可以停止构建,而不是在先前已有的正确的应用程序上部署一个错误的应用程序。然而,如果你正在使用JSP,你将不能在编译时使用javac找出语法错误,因为一般来说,只有在用户请求JSP文件时,JSP文件才被编译。

因此,缺少javac功能非常容易导致部署的JSP代码有缺陷。你可以通过使用Ant的jspc任务预编译你的JSP代码来避免这个问题。Jspc任务将把你的JSP文件转换为正确格式的Java servlet,因此你可以使用javac任务来编译它们,并捕获由此发生的任何语法错误。下面的例子说明了这一过程:

<target name="jsp"         description="Compile JSP files">    <jspc srcdir="${jsp}"          destdir="${src}"          package="com.oracle.example.jsp">        <include name="**/*.jsp"/>    </jspc>    <javac srcdir="${src}"           destdir="${tmp}"/></target>

在这个例子中,jspc任务将JSP文件放置在由srcdir属性指定的目录中,并把它们转换为Java servlet文件。然后将这些Java servlet文件放置在由destdir属性指定的目录中,在该目录中,它们将由javac任务进行编译。

然后,javac任务把${src}目录中由jspc生成的源代码编译为Java 字节码,并将其放置在由destdir属性指定的目录中,在这个例子中是${tmp}。在这个buildfile段中,jspc任务使我们能够发现本来可能由用户偶然发现的错误。

提高Ant生产效率的技巧

使用属性。通过使用属性,你只需进行最低限度的工作便可以使你的buildfile可重复使用。你还可以开发一个可重复使用的目标集合来快速开发新的buildfile。

使用相对的文件路径。相对路径是确保工程可移植性的一个好方法。绝对的文件路径不太灵活,同时还会使改变Java工程目录结构变得比所需的困难得多。

对buildfile进行注释。注释buildfile有许多方法。其中一个方法就是将一个描述(description)属性添加到目标中。这会使代码的可读性更好。

阅读文档。Ant的文档是全面的,且包括了许多有用的例子。

向Ant用户团体求助。你可能会遇到Ant的正式文档不能解决的问题,在这种情况下,可以向Ant的用户邮件列表求助。

扩展Ant的功能

你可能会遇到Ant的核心任务和可选任务不能满足你的需要的情况。然而,可能有第三方已经解决了这个问题。要了解这方面的更多内容,请参考Ant网站(jakarta.apache.org/ant) 并点击"External Tools and Tasks(外部工具和任务)"链接。

编写你自己的任务。当标准的Ant任务和第三方团体都不能提供满足你需要的任务时,就该是考虑自己动手的时候了。在这种情况下,你可以通过编写自己的任务来扩展Ant的功能。记住,Ant是源代码开放的,所以你能够看见和重复使用所有核心任务的源代码。

使用内部脚本。当任务太具有针对性而不能被重复使用时,你可以编写一个嵌套在script任务中的内部脚本。内部脚本是可移植的(它们将运行在Ant正在运行的任何环境中),但是需要第三方库。

谨慎地使用外部脚本。编写用于执行Ant不支持的任务的外部脚本可能是极具吸引力的,但是你应该谨慎地编写外部脚本,因为它可能会影响buildfile的可移植性。

结论

Ant是一个用于构建和部署Java工程的功能非常强大和全面的工具。对于Java开发人员来说,Ant提供了大量有用、省时的任务,能够帮助你使Java工程达到更高层次。

Michel Casabianca (casa@sweetohm.net)是为移动操作者提供游戏服务的法国公司In-Fusio的软件工程师,他还与其他人合著了《XML袖珍参考手册》( XML Pocket Reference)一书(2001年由O'Reilly出版)。

使用Ant的其他方式

在本文中,我已经讨论了使用Ant构建Java工程的典型方法。现在,让我们来看一些能够表明Ant在其他领域也一样有用的真实例子。

通过Ant安装应用程序

在Linux 或 UNIX环境中安装应用程序包括许多难度不同的任务:查找应用程序文档库、扩展它、编辑设置或启动脚本以设定主目录、修改脚本以使它们可执行等等。Ant能够管理这些所有任务,使通过编程方式开发用于将应用程序部署到服务器和桌面上的内部安装程序变得更容易。

Ant包括用于执行所有必需的安装功能的一系列任务。get或ftp任务使你能够检索文档库,而untar、gunzip或unzip任务使你能够操纵被检索的文档库。move和copy任务使你能够移动文件和编辑启动脚本。在UNIX或Linux系统上,Ant还提供了一个用于编辑脚本的文件许可(例如,使它们可执行)的chmod任务。

用Ant管理XML文件

在Ant的核心包里,有使用可扩展样式表语言转换(Extensible Stylesheet Language Transformations ,XSLT)样式表验证和转换XML文件的任务。使用Ant脚本,你可以自动化XML管理以便从XML文件生成文档(正像你可以使用makefile生成基于LaTeX的文档一样)。

还有许多用于管理XML文件的其他任务;参见Ant文档中的"外部工具和任务"部分了解更多的信息。例如,你可以使用Xpath表达式转换、合并或分离文件,甚至可以从中提取部分。

这是管理基于XML的文档的一个有用方式,你可以以这种方式生成网站。例如,Editions O'Reilly(O'Reilly的法国分公司)的网站 www.oreilly.fr 就是使用Ant生成的。整个网站(300多个页面)是在不到40秒的时间内在一个低端PC上生成的。

原创粉丝点击