在任何稳固的软件工程项目里构建工具都是开发人员工具包里最重要的一个部件之一没有一个可靠的构建工具编译包装和发布过程都会从复杂性和时间需求等方面影响实际的编程过程
用于Java开发人员的构建工具选择一直被局限于原有的基于UNIX的工具例如MakeMake及其开放源代码的派生工具能够完成任务但是正式严肃的工作常常还是要依赖于调用UNIX或者Windows命令来完成这就意味着Java代码即使能够做到跨平台和编写一次就能各处使用构建系统一般还是只能依赖于某种特定的平台
Java开发人员看到了这个问题并意识到通过提升Java平台的功能他们能够创建一个更加强大的构建工具这个工具是专门为Java程序人员设计的而且不会依赖于任何特定的平台这就是Ant一个由Apache基金会的Jakarta项目所管理的项目
Ant的配置文件是用XML文档编写的所以Java程序员应该已经很熟悉其的语法了这同Make声名狼藉的不友好句法形成了鲜明的对比更重要的是构建系统用来构建项目的所有动作也就是任务也是用Java编写的所以同样的构建文件能够被运行在任何可以使用Java编译器的地方在Ant里所有的东西都是独立自主的
在本文里我们将看到如何安装Ant如何创建用于构建项目的配置文件以及如何使用可用的内置系统和条件任务
安装Ant
要开始的话我们就需要先去Ant主页它上面有最新的发行版本在线使用手册和FAQ在下载和安装Ant以前你需要先安装Java开发工具包(或更高版本)需要设置JAVA_HOME环境变量在你的可执行路径里还需要javac编译器
你可以从Jakata网站下载预编译的ANT你还要用到可选的Java Archive(JAR)文件其包含的任务能有助于与其他开发工具进行集成Ant也是开放源代码软件所以如果你想修改任何内部组件来使其适应于自己的开发环境这没有问题你要做的只是下载源代码但是要注意的是Ant灵活性极强这一点我们会在下一篇文章里看到向Ant添加功能是很容易的而且不需要更改源代码
一旦下载完了二进制包你只需要简单地把文件解压到希望安装Ant的地方对于Windows系统解压到c:\ant\在UNIX系统上你可能希望安装到/usr/local/ant/或者/opt/ant/下
下一步你需要设置自己的环境变量即ANT_HOME在Windows上假如我们安装到c:\ant目录下图A所示的命令会正确地设置你的环境变量
图A设置Windows的环境变量
在UNIX系统上假设我们安装在/usr/local/ant目录下图B所示的命令会正确地设置你的环境变量
图B设置UNIX的环境变量
要在Windows或者UNIX系统上安装可选的任务你需要把可选的jar文件复制到$ANT_HOME/lib/目录下Ant或者antbat脚本会自动地把jar文件追加到类的路径下
现在我们测试一下确信Ant已经正确安装好了在命令行下输入ant你应该会看到一条信息见图C说Ant无法定位Buildxml文件这正是我们所期望的因为我们还要配置和创建项目文件
图C创建文件错误信息
既然Ant已经准备好了读取项目文件就让我们看看项目文件是什么样的吧创建项目
创建项目
为了让开发人员的日子更加好过一点Ant的配置文件是使用XML文档编写的这样开发人员不用去担心空白的问题(Makefiles就有这个问题)而且许多开发人员都已经能够正确编写XML了
Ant一启动就会自动地加载一个叫做Buildxml的项目配置文件如果想给这个项目配置文件取别的名字你可以使用buildfile标记来运行ant就像下面这样
ant buildfile Project_configurationxml
在Listing A所示的SimpleBuildxml配置文件里你会看到一个项目标签它带有三个属性名字缺省值和basedirAnt使用说明里有Ant配置文件里每个标签的详细文档你可能要使用Ant使用说明作为参考书来了解哪些是必需的标签哪些有缺省值
在项目标签里你会看到属性和目标标签属性标签创建的变量能够被任务和变量扩展访问正如我们在后面所要看到的一样有一些变量像日期和时间能够在任务内部进行设置所以不是所有的变量都会被明确地定义
在属性标签后面你会看到目标标签你可以定义多个目标每一个都有不同的名字你会注意到目标标签的名字是compile这碰巧和项目标签里的缺省值相对应这就意味着我们在执行Ant的时候它会自动地启动compile目标
目标里有许多的任务Ant按顺序来执行它们你会发现构建包装和发布过程中几乎每一件事都可以由Ant的任务来处理
在进行简单的构建时我们使用tstamp任务来把当前的日期和时间设置到环境变量里下一步我们会使用mkdir任务来创建一个叫做${build}的目录(假设它并不存在这是我们脚本里命令解释程序扩展的第一个例子Ant会自动把${build}扩展到属性构建所设置的值里在这种情况下是build字符串)
最后我们会使用javac任务来编译来自src目录的源代码并把输出保存到构建里
在运行Ant时我们会让输出来显示每个目标执行的状态如图D所示
图DAnt的输出
一个更加深入的例子
现在我们看看使用多个目标构建一个稍微复杂一点的配置的例子
在Listing B所示的Mediumxml例子里配置内容被分成的目标比SimpleBuildxml例子里的更多把构建过程分成不同的目标意味着Ant可以从任何点进入构建过程在SimpleBuildxml里我们只用简单地编译Java源代码但是在这个例子里我们启动环境(init)编译代码(compile)把代码包装进jar(package)再把结果复制进产品所在的位置(dist)我们还有一个在任何代码编译以前通过还原来清除环境的任务
在缺省状态下我们会依次运行initcompilepackage然后是dist你可以看到每个对象都有已定义的相依性Ant在依赖相依性的目标完成以前就完成好相依性缺省的目标是dist所以在命令行运行ant会完成所有的任务
然而我们可以通过在命令行指定用所希望的目标来执行所有步骤中的一部分例如我们可以只包装代码而不发布它把更大的项目分成多个目标能够允许开发人员迅速地进行分段构建而不必等待完整构建这会有助于调试和保证高质量的过程
内置的任务
既然你已经看过了如何创建一个项目文件那我们就看一些内置的任务你会希望看一下Ant的文档来获得任务的细节因为那里所提供的信息比我们这里所涉及的要多
文件系统任务
你可能会经常使用Ant来完成系统任务移动修改复制和删除文件在发布和清除临时文件时你会需要移动文件这就是为什么懂得文件系统工具的使用是有必要的原因了
Listing C所示的Fsxml 例子给filesystem回应了一条信息@…@标志是Ant如何进行文本替换的标识要替换文本就要在将被替换的文本前后加上@标志在信息被复制到磁盘以后我们创建两个目录复制文件在我们复制的时候对磁盘上的文件进行标志替换再删除一个已复制的文件图E是在Fsxml构建文件上运行Ant的输出结果
图E Filesystem输出实例
使用条件
在Ant里构建条件不太容易由于Ant构建任务和目标的方法你不得不小心地构造你的陈述式只有当属性被设置成真值的时候条件才能通过执行对象来工作你可以使用andor和not陈述式来构造你的条件在一个条件被发现为真时你可以使用antcall任务来执行另一个目标让我们来看一个简单的例子它会确定可选的声音任务是否可用以及它是否在UNIX或者Windows上可用
在Listing D所示的SoundConditional的例子里你会看到条件任务会调用两个条件陈述式 condWinSound和condUnixSound但是两者都不会主动执行除非条件属性被设置条件目标会检查包装是否可用(这是可选的jar文件一部分)以及在哪个平台上可用
包装
现在你应该已经准备好开始把自己的软件项目转移到Ant构建工具上了Ant正在越来越多地被开发人员用来支持大型的Java项目——而且是因为有了好的理由这些工具是面向Java的跨平台的而且一般都比面向UNIX的工具要更容易使用希望本文能够让你看到Ant的力量也能有助于提高你所在组织的产出在以后的文章里我们会来看通过创建自己的任务如何来扩展Ant