一、Ant简介
Ant
是一个Apache
基金会下的跨平台的构件工具。
由于Ant
是基于Java
的,所以需要Java
环境的支持,也就是配置好 JAVA_HOME
和 ANT_HOME
环境变量分别指向Java
和Ant
目录,并将${ANT_HOME}/bin (Unix)
或 %ANT_HOME%/bin (Windows)
配置到PATH
中。
如果配置了Java
及Ant
环境变量,则可以直接使用了,否则必须在运行前指定其运行路径。
Windows
环境:
-
set ANT_HOME = ant的安装目录的根目录
-
set JAVA_HOME = JDK安装的根目录
-
set PATH = %PATH%;%ANT_HOME%in;
Linux
或Unix
环境:
-
export ANT_HOME = ant的安装目录的根目录
-
export JAVA_HOME = JDK安装的根目录
-
export PATH = ${PATH}:${ANT_HOME}/bin;
示例小程序
预备知识:
Ant
工具的配置文件采用XML
任务树的形式。- 运行时没有指定文件名,则会自动搜索
build.xml
文件。
创建FirstTestAnt.xml
-
-
<project name="first ant example" default="firstExample">
-
<target name="firstExample">
-
<echo message="这是一个简单的Ant实例"></echo>
-
<echo message="操作系统为:${os.name}"></echo>
-
<echo message="根目录为:${basedir}"></echo>
-
<echo message="ant文件的信息:${ant.file}"></echo>
-
<echo message="ant的版本:${ant.version}"></echo>
-
<echo message="项目的名称:${ant.project.name}"></echo>
-
<echo message="Java的版本:${ant.java.version}"></echo>
-
</target>
-
</project>
运行如下命令:
-
D:【当前目录】>ant -f FirstTestAnt.xml
-
Buildfile: D:360极速浏览器下载FirstTestAnt.xml
-
-
firstExample:
-
[echo] 这是一个简单的Ant实例
-
[echo] 操作系统为:Windows 8.1
-
[echo] 根目录为:D:360极速浏览器下载
-
[echo] ant文件的信息:D:360极速浏览器下载FirstTestAnt.xml
-
[echo] ant的版本:Apache Ant(TM) version 1.9.7 compiled on April 9 2016
-
[echo] 项目的名称:first ant example
-
[echo] Java的版本:1.8
-
-
BUILD SUCCESSFUL
-
Total time: 0 seconds
注:如果文件名是build.xml
就直接在当前的目录下直接使用ant
命令即可。
二、Ant配置文件
2.1 Ant构件文件
Ant
的构件文件是基于XML
的方式进行编写的,其默认的名称为build.xml
,当然也可以取别的文件名称(此时要在构建时指定具体的构件文件名称)。
在Ant
工具中,每一个构件文件中必须包含一个project
元素,project
元素作为XML
树的根节点。一个project
元素可以包含多个target
元素作为叶子节点,每一个target
元素可看作Ant
工具的基本执行单元,同时在target
单元之间可存在或定义依赖关系。在每一个target
中可包含多个具体执行的元素(也可看作Ant
任务),可执行的元素定义了这个操作具体要做的事情。
2.2 project元素
project
元素是Ant
构件文件中的根元素,Ant
构件文件至少应该包含一个project
元素。在project
元素下可定义一个或多个target
元素。当运行Ant
工具时,可以选择执行project
元素下的一个或多个target
。如果没有指定要具体执行的target
,则Ant
会执行project
元素中定义的默认的target
。
在Ant
工具中,一个project
元素包含3个属性:name
、default
和basedir
。这三个属性不是必须的,可以根据项目的需要进行选择。
2.2.1 name属性
name
属性的作用就是给project
元素起一个名字。
2.2.2 default属性
default
属性用于指定project
默认执行时所执行的target
。Ant
从1.6.0版本后,每个project
元素里都包含一个隐藏的target
元素,这个隐藏的target
元素包含所有构件文件中顶级的ant tasks
和ant types
。
运行Ant
工具时加入-projecthelp
选项,这个隐藏的target
会在project
初始化时被执行。
2.2.3 basedir属性
basedir
属性在Ant
工具中用于指定基路径的位置。该属性可以被basedir property
覆盖。当覆盖时,该属性被忽略。如果该属性以及basedir property
都没有设定,则Ant
就是用构件文件的父目录作为基准目录。在Ant
的target
元素中可以通过${basedir}
来获取基目录的位置。
基路径可以这样理解:就是文件中其他部分所有相对路径的起始路径,或者说调用${basedir}
时的使用路径。
2.2.4 description子元素
description
属性对于对project
及其内容进行相关说明。当Ant
运行时,加上-projecthelp
选项,命令行中就会输出description
属性中的说明信息。
-
-
<project name="first ant example" default="A">
-
<description>
-
描述信息:这是一个简单的Ant实例。
-
</description>
-
<target name="firstExample">
-
<echo message="这是一个简单的Ant实例"></echo>
-
</target>
-
<target name="A">
-
<echo message="这是A"></echo>
-
</target>
-
</project>
2.3 target元素
target
元素是Ant
工具的基本执行单元,每个target里包含一个或多个具体的操作。一个target
可以依赖于其他的一个或多个target
。target
包含5个基本属性:name
、depends
、if
、unless
、和description
。
2.3.1 name属性
name
属性就是target
元素的名称。每一个target元素必须要有一个name属性且name值必须唯一。当要执行具体的target
元素时就通过名称指定。
注意事项:据Ant
工具的文档上的说明,name
建议避免使用逗号“,”和
空格“ ”
。这些符号可能在以后的Ant
版本中不能再使用,因为在整合集成工具(如Eclipse
)时,这些符号可能会产生冲突,因为在开发工具中他们可能有特殊的用途。
2.3.2 depends属性
depends
属性用于描述target
间的依赖关系。depends
中可以是一个或多个target
元素名称,多个target
元素名称使用逗号“,”
来分割。
Ant
工具的depends
属性只指定了target
元素间被执行的顺序关系。如果当前的target
元素无法运行,但这种depends
关系对于这个target
元素所依赖的其他target
元素并没有影响,这些被依赖的target
元素会被正常执行。Ant
会依照Depends
属性中target
出现的顺序(从左到右)依次执行每个target
。
2.3.3 if属性
if
属性主要用于验证在执行target
前所必须设定的属性。如果if
指定的属性没有被设定(也就是不存在),那么这个target
不会被执行。
例如:要验证系统是否安装了JDK
,若安装了JDK
就输出JDK
的版本。
-
-
<project name="if ceshi" >
-
<target name="checkJavaVersion" if="ant.java.version">
-
<echo message="Java的版本为:${ant.java.version}" />
-
</target>
-
<target name="linshi" if="a">
-
<echo message="我不应该出现的!" />
-
</target>
-
</project>
运行结果:
-
D:360极速浏览器下载>ant -f ceshi.xml checkJavaVersion linshi
-
Buildfile: D:360极速浏览器下载ceshi.xml
-
-
checkJavaVersion:
-
[echo] Java的版本为:1.8
-
-
linshi:
-
-
BUILD SUCCESSFUL
-
Total time: 0 seconds
可以看出,a
这个变量值不存在,所以linshi
这个target
没有运行。
2.3.4 unless属性
unless
属性的功能与if
属性功能正好相反。也就是说,如果unless
属性中指定的属性没有被设定,那么这个target
元素将会被执行。
注意:if
和unless
属性只能限定本target
元素的功能是否被执行,但是它们并不能限制这个target
依赖的target
的执行。
简单来说:<target name="targetA" depends="targetB" if="Aproperty">
,同时Aproperty
没有被设定,当执行targetA
时,虽然targetA
不会被执行,但是targetB
会正常地被执行。
2.3.5 description属性
是一个描述性的子元素,使用-projecthelp
可以查看,但是都会被提取到全局描述,但是通过向description
中添加描述,使用户能够更好地了解这个target
元素要执行的功能,这是一个良好的习惯。
2.4 task和property元素
task
元素是Ant
工具执行的功能单元,可以看作是一段可执行的代码。property
元素可以看作是一个名字和一个值的对应关系,用于定义一些需要用到的变量。task
和property
都可在target
中整合使用。
2.4.1 task元素详解
task
在我理解看来,是一种泛称,并不是一个具体的标签名,task
是一段可执行的代码,在task
内封装了执行的细节。每个task
可以有一个或多个属性,下面介绍的property
元素就是task
的一种。我是这样理解的task
就是一个任务。Ant
提供了大量的核心task
和可选task
,除此之外,Ant
还允许用户定义自己的task
,这大大扩展了Ant
的功能。
注意:如果task
没有被执行的情况下,设定的属性将不会生效。如果用户在task
执行后进行这些设定,那么task
中原本的这些属性将会被覆盖。
2.4.2 property元素详解
property
元素可看作变量或参数的定义,在一个project
中可以有很多属性(properties
)。可以在构件文件中用property
,也可以在Ant
之外进行设定。例如,可以建立一个独立的build.property
文件用于放置编辑时所必须的property
元素,然后在构件文件中引用此文件。这样便于对property task
进行统一管理。
具体的引用方式如下:
<property file="build.properties"/>
每个property
元素有一个名字和一个值。property
元素可用作task
的属性值。在task
中是通过将属性名放在“${”
和“}”
之间,并放在task
属性值的位置来实现的。Ant
工具提供了一些内置的属性,可以直接引用。例如:${os.name}
对应当前操作系统的名称。Ant
可以得到的系统属性的列表与Java文档中System.getProperties()
方法能得到的属性一致。
除了Java
的系统属性,Ant
还定义了一些自己的内置属性。如下:
- basedir:
project
基目录的绝对路径(与<project>
的basedir
属性一样) - ant.file:
buildfile
的绝对路径 - ant.version:
Ant
的版本 - ant.project.name:当前执行的
project
的名字,由<project>
的name
属性设定 - ant.java.version:
Ant
检测到的JVM
的版本
一个简单完整的Ant
工具构件Java
项目的实例:
-
-
<project name="MyProject" default="dist" basedir=".">
-
<property name="src" value="."/>
-
<property name="build" value="build"/>
-
<property name="dist" value="dist"/>
-
-
<!-- 初始化target建立一个用于存放class文件的目录 -->
-
<target name="init">
-
<!-- Create the time stamp -->
-
<tstamp/>
-
<!-- Create the build directory structure used by compile -->
-
<mkdir dir="${build}"/>
-
</target>
-
-
<!-- 编译源文件 -->
-
<target name="compile" depends="init">
-
<!-- 编译${src}目录下的源文件,生成的class文件存放到${build}目录中 -->
-
<javac srcdir="${src}" destdir="${build}"/>
-
</target>
-
-
<target name="dist" depends="compile">
-
<!-- Create the distribution directory -->
-
<mkdir dir="${dist}/lib"/>
-
<!-- 把所有${build}目录下的class文件打包到MyProject-${DSTAMP}.jar 文件中 -->
-
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
-
</target>
-
-
<target name="clean">
-
<!-- 删除${build}和${dist}目录下的所有文件和目录 -->
-
<delete dir="${build}"/>
-
<delete dir="${dist}"/>
-
</target>
-
-
</project>
MyProject
是一个常用的构件文件,这个构件文件的作用是对项目的源文件进行编译,并打包生成jar
文件。
上面的property
在target
元素中被引用。其中,src
是源文件的根目录,build
是编译时的目录,dist
就是打包时的目录。在构件文件中tstamp
用于获取当前的时间,mkdir
用于建立目录,javac
用于编译Java
程序,jar
用于打包jar
程序,delete
用于删除目录,这些都是Ant
工具内置的功能task
。
上面构件文件解析:
init target
的作用是进行初始化工作,创建build
目录;compile target
的作用是对Java
程序的源代码进行编译,同时依赖于init target
,并在init
执行后执行;dist target
的作用是打包生成jar
文件,依赖于compile target
;clean target
的作用是删除已经打包的jar
程序。
2.5 token filters元素详解
token
(标记符)也是一种泛称,在一个project
元素中可以有很多tokens
,我的理解就是一种标记符过滤器。通常tokens
采取@token@
的形式,其中token
是filter task
中设定的token
名称,而@为默认的token
开始和结束符。
另外,如果一个文件中发现一个@token@
形式的token
,但没有filter
与这个token
关联,那么是不会发生任何作用(不进行过滤行为)的。
2.5.1 path-like结构
这种结构通常在定义path
和classpath
元素时使用,可称为路径匹配。如果在构件文件中可以使用“:”
和“;”
作为分隔符,指定对path
和classpath
元素的引用。那么,Ant
工具会自动把分隔符转换为当前系统所使用的分隔符,然后进行分割。当需要指定类库的路径时,也可以使用嵌套元素。
2.5.2 命令行变量
命令行变量是指在命令行模式中传入的参数,而这些传入的参数可以在执行的程序或命令中使用。在Ant
工具中有些task
可接收参数,并将其传递给另一个进程。为了能在变量中包含空格子夫,可包含空格字符,可使用嵌套的arg
元素。
arg元素具有以下属性:
- value:一个命令行变量,可包含空格字符,但只能用一个
- line:空格分隔的命令行变量列表
- file:作为命令行变量的文件路径,被文件绝对路径替代
- path:可作为单个命令行变量的path-like字符串,也可作为分隔符,Ant会将其转变为特定平台的分隔符。
<arg values="-l -a"/>
是一个含有空格的单个命令行变量。
<arg line="-l -a"/>
是两个空格分割的命令行变量。
<arg path="/dir;/dir2:dir3"/>
是一个命令行变量,其值在DOS系统为dir;dir2dir3;在UNIX系统为/dir:/dir2:dir3。构件文件中的id属性可用来引用这些元素。如果需要重复地复制相同的XML代码块,这个属性就很有用。如多次使用<classpath>元素。
三、Ant运行
Ant
工具有两种常用的运行方式:一是在命令行直接运行,另一种是在支持Ant
工具的集成开发环境(IDE)中运行。
3.1 在命令行运行Ant工具
如果将Ant
的bin
目录设定到环境变量中,就可以运行Ant
工具了,否则必须得设定临时环境变量,才能运行。如果都没有,系统将找不到Ant
工具。
输入Ant
命令而不输入其他选项时,Ant会在当前目录中查找build.xml
文件,并执行project
元素中default
属性指定的target
。
3.2 常用Ant命令选项
3.2.1 buildfile选项
利用Ant
工具进行开发时,Ant
的构件文件名称可能不是build.xml
或者目录不在当前目录,但需要在当前目录执行Ant
命令。这时可以在执行ant
命令时加上-buildfile
的参数选项来指定具体要执行的构件文件位置。这里的-buildfile
选项用于指定具体要执行的构件,可指定文件名加路径。-buildfile
的简称可以写成-file
或-f
,其执行效果是相同的。
3.2.2 projecthelp
projecthelp
选项输出项目的描述信息和项目target
的列表。如果想在执行构件文件之前了解构件文件包含哪些功能,可以添加此选项。
先列出有描述的target
,然后再列出没有描述的target
。也可以用-p
选项代替-projecthelp
,两者作用等同。
3.2.3 -D<property>=<value>选项
该选项可以让用户设定一些属性,以覆盖构件文件中指定的属性值。
同样地,可以用这种办法来指定一些环境变量的值。可以用property task
来存取环境变量,只需要把-DMYVAR=%MYVAR%(Windows)
或-DMYVAR=$MYVAR(UNIX)
传递给Ant工具就可以在构件文件中通过${MYVAR}来引用这些设定的环境变量。
3.3 Ant命令行选项总结
- -help,-h:显示Ant命令的帮助信息
- -projecthelp,-p:显示当前project的帮助信息,主要是project中包含的target
- -version:显示Ant的版本信息
- -diagnostics:显示Ant项目的运行环境、依赖库等信息,为错误诊断和报告提供一些有用的帮助信息
- -quiet,-q:隐藏Ant执行时的提示信息输出。命令行将不会输出具体target的执行信息
- -verbose,-v:显示Ant执行的详细信息,包括操作系统和Java环境等信息
- -debug,-d:显示Ant执行时的调试信息、详细的log信息
- -emacs,-e:显示不经修饰的日志信息,就是说不输出额外的日志信息
- -lib<path>:指定一个类库所在的位置(jar文件的位置),让Ant工具可以使用这些类文件。path类型指定类库的位置
- -logfile<file>,-l<file>:指定Ant执行时日志输出文件,让日志输出到指定文件而不在命令行输出。
- -logger<classname>:指定要输入日志信息的类名,指定的类都将会输入日志信息
- -listener<classname>:指定一个类作为这个project的监听器
- -noinput:表示不能接受输入信息
- -buildfile<file>,-file<file>,-f<file>:指定要执行的构件文件的位置及名称
- -D<property>=<value>:用于设定一些变量,这些变量可以再target中直接引用,或覆盖已设定的属性值
- -keep-going,-k:当执行所有的target时不需要使用depends设定依赖关系
- -propertyfile<name>:引用指定的属性文件中的属性,若同时指定-D<property>=<value>,则-D指定的属性优先。
- -inputhandler<class>:指定一个类来处理输入的请求
- -find<file>,-s<file>:查找构件文件,并执行找到的构件文件
- -nice number:设定主线程的数目,number为指定的数目。默认时主线程总数为5,最小值为1,最大值为10
- -nouserlib:运行Ant时不使用${user.home}/.ant/lib下的jar库
- -noclasspath:运行Ant时不使用classpath变量中指定的类路径。
3.4 Ant中使用环境变量和Java系统属性
3.4.1 Ant中使用环境变量
- JAVACMD:若配置了
JAVACMD
,Ant
工具会以JAVACMD
来替代JAVA_HOME
。换句话说,你想换一个系统默认的java
环境来编译项目时,可以设置JAVACMD
这个环境变量。 - ANT_OPTS:用于设置
Java
的优化属性,作用相当于在Ant
工具中直接设定JAVA_OPTS
参数。如果要设定JAVA
堆栈大小就可用这个环境变量进行设置 - ANT_ARGS:用于设置
Ant
工具的命令行参数。例如,可以设定ANT_ARGS
指向多个不同的日志文件
3.4.2 Java系统属性
在Ant
工具中可以直接使用Java
的系统属性,这些属性与Java System
类中定义的一致。
可以参考Java API
中的java.lang.System
的getProperties
方法:
键 | 相关值的描述 |
---|---|
java.version |
Java 运行时环境版本 |
java.vendor |
Java 运行时环境供应商 |
java.vendor.url |
Java 供应商的 URL |
java.home |
Java 安装目录 |
java.vm.specification.version |
Java 虚拟机规范版本 |
java.vm.specification.vendor |
Java 虚拟机规范供应商 |
java.vm.specification.name |
Java 虚拟机规范名称 |
java.vm.version |
Java 虚拟机实现版本 |
java.vm.vendor |
Java 虚拟机实现供应商 |
java.vm.name |
Java 虚拟机实现名称 |
java.specification.version |
Java 运行时环境规范版本 |
java.specification.vendor |
Java 运行时环境规范供应商 |
java.specification.name |
Java 运行时环境规范名称 |
java.class.version |
Java 类格式版本号 |
java.class.path |
Java 类路径 |
java.library.path |
加载库时搜索的路径列表 |
java.io.tmpdir |
默认的临时文件路径 |
java.compiler |
要使用的 JIT 编译器的名称 |
java.ext.dirs |
一个或多个扩展目录的路径 |
os.name |
操作系统的名称 |
os.arch |
操作系统的架构 |
os.version |
操作系统的版本 |
file.separator |
文件分隔符(在 UNIX 系统中是“/”) |
path.separator |
路径分隔符(在 UNIX 系统中是“:”) |
line.separator |
行分隔符(在 UNIX 系统中是“/n”) |
user.name |
用户的账户名称 |
user.home |
用户的主目录 |
user.dir |
用户的当前工作目录 |
常用到的系统属性:
- path.separator:路径分隔符,UNIX和Windows不同
- ant.home:Ant工具根目录的位置
- basedir:执行构件文件的调用目录
- os.name:操作系统的名称
- line.separator:换行符
- java.home:Java的根目录位置
- java.version:Java的版本
- user.home:用户的home目录,在Linux和UNIX中经常用到
- java.class.path:Java库文件的位置