本章的目标:通过Ant的Datatype和特征来控制Ant构建,打包并运行了一个Java程序这个过程。
用编程语言的术语讲,由Ant任务所展现的是运行时库提供的功能。任务只有和数据一同使用时才真正有用,因为它需要从数据中获取运行的细节。Java是一种面向对象的语言,也就是说它把数据和功能全部封装在类中。尽管Ant使用Java编写的,但它却将“完成工作”的任务和“任务所需”的数据区分开了————其中Datatype就代表了数据。Ant还有一个类似于变量的概念,特征。
为了把数据传递给任务,你需要在构建文件中创建并引用Datatype和特征。和任务一样,Datatype也只是一段XML,它可以罗列出一些任务使用的文件和资源。
预备知识)
就像Java有类和变量一样,Ant有Datatype和特征。
什么是Ant Dataype?
一个Ant Datatype等价于一个Java类————在底层,它们实际上就是由Java类实现的。Datatype存储了大量的构建过程中使用的复杂信息——比如,一个带编译的文件列表或者一个待删除的目录集。Ant必须管理这些信息,所以构建文件需要一种方法来描述它们。Ant Datatype应运而生。Datatype扮演了任务参数的角色。它们可以在一个任务内部声明,也可以在任务外部定义,并为它起个名字,然后再把这个名字传给任务。这样就能够跨多个任务共享一个Datatype了。
一个典型的Ant构建必须妥善处理文件和路径的问题,尤其是类路径。很自然地,Datatype能够处理文件和路径。文件集(fileset)和路径(path)这两种Datatype会在整个构建文件中随处可见。
"文件集"可以列出哪些文件需要编译,打包,复制,删除或者测试。例如,定义一个包含所有Java文件的文件集是相当简单的:
<fileset id="source.fileset" dir="src" includes="**/*.java" />
通过提供id属性,我们可以定义一个引用(reference)。这个引用能够在随后任何需要fileset的地方使用。例如,将源码带复制到另一个目录中,我们就可以再次使用source.fileset:
<copy todir="backup">
<fileset refid="source.fileset" />
</copy>
只有构建文件预先定义了这个文件集(fileset),比如在之前的目标(target)中进行了定义,引用才能正常工作。Ant在遇到未定义的引用时,会产生错误并失败。
Ant特征
Ant特征并不是构建过程中共享信息的关键,更是使用者从外部控制Ant的重要手段。例如,假设出于测试的目的,需要修改构建文件,让它们使用一个不同版本的第三方库,那么完成这个修改非常简单:
ant -Dhost=localhost (可以使用ant -help查看命令行可选项-D)
我们也可以在构建文件内部设置的特定的值。
<property name="host" value="localhost" />
无论哪种情况,现在Ant的host特征一定等于"localhost"。想要在构建文件中使用这个值,我们可以把它嵌入到任何字符串内。比如
<echo>host=${host}</echo>
如果特征已经定义,${host}将被替换为特征的值;否则,它还会保持原来的样子。
与Java变量不同,Ant的特征是不可变的(immutable):你不能修改它们。第一个使用某个特征的任务,项目或者用户一旦设置了特征值,它就在整个构建过程中固定不变了。这条规则与大多数语言是相反的,但是这条规则让你能够从外部控制构建文件。