ant学习笔记

转自 :李飞虎 blog :http://hi.baidu.com/annleecn/blog/category/ant%2Clog4j%2Cjunit

1,ant介绍

ant构建工具,我们能用到的多是它的编译,拷贝,复制,运行命令等功能.
ant的好处:1,跨平台,因为ant是使用java实现的;2,使用简单;3,语法清晰;4,功能强大.
ant做的很多事情,大部分是曾经一个叫make的工具所做的,make更多应用于c/c+ +;ant更多应用于java.

2,ant安装

到ant官方网站(http://ant.apache.org)上下载ant,我使用的是1.7.1.下载解压后,增加环境变量:
ANT_HOME:C:\TDDOWNLOAD\apache-ant-1.7.1
在path环境变量中加入ant的bin目录:%ANT_HOME%\bin

如果要让ant能支持JUnit,需要将JUnit的JUnit.jar放置在ant的lib目录,并记得改变CLASSPATH中原先有关于JUnt的设定,如:%ANT_HOME%\lib\junit.jar

cmd进入命令行界面,运行ant命令,可以测试是否安装成功

3,第一个ant脚本

3.1,用文本编写一个HelloWorld.java程序,代码如下:
package test.ant;
public class HelloWorld{
public static void main(String[] args){
   System.out.println("hello world!");
}
}

3.2,用ant完成编译和运行
建立一个build.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="HelloWorld" default="run" basedir=".">
<property name="src" value="src"/>
<property name="dest" value="classes"/>
<property name="hello_jar" value="hello1.jar"/>
<target name="init">
   <mkdir dir="${dest}"/>
</target>
<target name="compile" depends="init">
   <javac srcdir="${src}" destdir="${dest}"/>
</target>
<target name="build" depends="compile">
   <jar jarfile="${hello_jar}" basedir="${dest}"/>
</target>
<target name="run" depends="build">
   <java classname="test.ant.HelloWorld" classpath="${hello_jar}"/>
</target>
<target name="clean">
   <delete dir="${dest}"/>
   <delete dir="${hello_jar}"/>
</target>
<target name="rerun" depends="clean,run">
   <ant target="clean"/>
   <ant target="run"/>
</target>
</project>

3.3,解释上面的配置文件
<?xml version="1.0" encoding="UTF-8" ?>,指定一下版本号和编码方式,几乎所有的XML文件的第一行都是这样.

<project name="HelloWorld" default="run" basedir=".">,ant的所有内容必须包含在project元素里面,basedir是工作的根目录,default是默认要做的事.

<property name="src" value="src"/>,指定变量

<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${dest}"/>
</target>,要运行的一个命令,depends是它所依赖的target,在执行前先检查depends是否被执行过,如果执行过则直接执行name的命令,否则先执行depends
的命令.

3.4,运行ant

新建一个文件夹,把HelloWorld.java文件放进去,在命令行进入build.xml文件所在的目录,再运行命令:ant;可以看到run命令以及它所依赖的命令都执行了一次.

如果只想执行某个命令,而不是默认命令,如执行build命令,则可以用:ant build;即格式为:ant + target name

4,整合多个build.xml文件的命令

在实际的工作过程中,可能会有一个项目分成很多个模块,每个模块因为由不同的人员负责,因此他们也写了build.xml文件,并且内容各不相同,这时要把它们整合到一起使用,这时有两个选择:
1,重新写一个build.xml;
2,利用他们已经写好的build.xml文件,进行整合.

例如,有三个小组,每个小组都有一个src文件夹和build.xml文件.这个时候可以建立三个文件夹src1,src2,src3,分别把他们的src和build放进去,然后写一个build.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="main" default="build" basedir=".">
<property name="bin" value="${basedir}\bin"/>
<property name="src1" value="${basedir}\src1"/>
<property name="src2" value="${basedir}\src2"/>
<property name="src3" value="${basedir}\src3"/>

<target name="init">
   <mkdir dir="${bin}"/>
</target>

<target name="run">
   <ant dir="${src1}" target="run"/>
   <ant dir="${src2}" target="run"/>
   <ant dir="${src3}" target="run"/>
</target>
<target name="clean">
   <ant dir="${src1}" target="clean"/>
   <ant dir="${src2}" target="clean"/>
   <ant dir="${src3}" target="clean"/>
</target>
<target name="build" depends="init,call">
   <copy todir="${bin}">
    <fileset dir="${src1}">
     <include name="*.jar"/>
    </fileset>
    <fileset dir="${src2}">
     <include name="*.jar"/>
    </fileset>
    <fileset dir="${src3}">
     <include name="*.jar"/>
    </fileset>
   </copy>
</target>
<target name="rebuild" depend="build,clean">
   <ant target="clean"/>
   <ant target="build"/>
</target>
</project>

OK,以上build.xml文件整合了三个build.xml子文件.

5,ant高级应用

property和xml include可以所build.xml中<property/>中的内容分离出来,共同使用,它们的优点如下:
property:维护简单,键值对容易记住;
xml include:不单可以提取出属性来,连target也可以

还是上面的例子,如果我想把src1,src2,src3这三个属性从xml中提取出来,可以新建一个文件all.properties,内容如下:
src1=D:\\study\\ant\\src1
src2=D:\\study\\ant\\src2
src3=D:\\study\\ant\\src3

然后,build.xml文件可以这样按下面的内容写,别人只需要更改配置文件,而不需要更改build.xml文件了.
<?xml version="1.0" encoding="UTF-8" ?>
<project name="main" default="build" basedir=".">
<property name="file" value="all.properties"/>
<property name="bin" value="${basedir}\bin"/>

<target name="init">
   <mkdir dir="${bin}"/>
</target>

<target name="run">
   <ant dir="${src1}" target="run"/>
   <ant dir="${src2}" target="run"/>
   <ant dir="${src3}" target="run"/>
</target>
<target name="clean">
   <ant dir="${src1}" target="clean"/>
   <ant dir="${src2}" target="clean"/>
   <ant dir="${src3}" target="clean"/>
</target>
<target name="build" depends="init,call">
   <copy todir="${bin}">
    <fileset dir="${src1}">
     <include name="*.jar"/>
    </fileset>
    <fileset dir="${src2}">
     <include name="*.jar"/>
    </fileset>
    <fileset dir="${src3}">
     <include name="*.jar"/>
    </fileset>
   </copy>
</target>
<target name="rebuild" depend="build,clean">
   <ant target="clean"/>
   <ant target="build"/>
</target>
<target name="test">
   <ant dir="${src1}" target="test"/>
   <ant dir="${src2}" target="test"/>
   <ant dir="${src3}" target="test"/>
</target>
</project>

有时候又想给每个小组的build.xml加入几个target,一种做法是在每个小组的build.xml中加上target,然后在总的build.xml文件中调用,但有种更好的办法.可以写一个include.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<property name="src" value="src"/>
<property name="dest" value="classes"/>
<target name="test">
<ant target="run"/>
</target>

然后更改小组的build.xml文件,在文件头加上以下内容:
<!-- include a xml file , it can be common on property , can be also a target -->
<!DOCTYPE project [
<!ENTITY share-variable SYSTEM "file:../include.xml">
]>
&share-variable;
这个时候,只要在include.xml中添加property,target,子build.xml会同时添加这些property和target,而且不会让子build.xml变得更复杂.
添加后的build.xml文件内容如下:

6.ant常用命令

6.1,设置和使用classpath

设置代码如下:
<classpath id="project.class.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
   <include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
<dirset dir="build">
   <include name="apps/**/classes"/>
   <exclude name="apps/**/*Test*"/>
</dirset>
<filelist refid="third-party_jars"/>
</classpath>

使用代码如下:
<target>
<javac>
   <classpath refid="project.class.path"/>
</javac>
</target>

6.2,输出信息

输出信息有两种写法:
1,<echo message="xxxx"/>
2,<echo>xxxx</echo>

输出一段XML
<echoxml file="subbuild.xml">
<project default="ann">
   <target name="ann">
    <echo>ann</echo>
   </target>
</project>
</echoxml>

6.3,引入一个XML文件

<import file="../common-targets.xml"/>

6.4,拷贝和删除文件,目录

拷贝一个文件:
<copy file="myfile.txt" fofile="mycopy.txt"/>

拷贝一个文件到指定目录:
<copy file="myfile.txt" todir"../some/other/dir"/>

拷贝一个目录到另一个目录:
<copy todir="../new/dir">
<fileset dir="src_dir"/>
   <exclude name="**/*.java"/>
</fileset>
</copy>

<copy todir="../dest/dir"
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>

拷贝一个文件集合到一个目录,同时建立备份文件:
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<globmapper from="*" to="*.bak"/>
</copy>

拷贝一个集合的文件到一个目录,并替换掉@TITLE@
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<filterset>
   <filter token="TITLE" value="Ann Lee"/>
</filterset>
</copy>

拷贝一个目录下的东西到另一个目录下
<copydir src="${src}/resources" dest="${dest}" includes="**/*.java" excludes="**/Test.java"/>

拷贝一个文件
<copyfile src="Test.java" dest="subdir/Test.java"/>

删除文件,目录,(拷贝中各种关于目录的操作也可以用在这里)

删除一个文件
<delete file="/lib/ant.jar"/>

删除一个目录
<delete dir="lib"/>

删除所有符合规则的文件(.bak文件)包括子目录
<delete>
<fileset dir="." includes="**/*.bak"/>
</delete>

删除当前目录下所有的文件和目录,包括当前目录
<delete includeEmptyDirs="true">
<fileset dir="build"/>
</delete>

删除当前目录下所有的文件和目录,不包括当前目录
<delete includeemptydirs="true">
<fileset dir="build" includes="**/*"/>
</delete>

删除当前目录下所有的svn相关文件(因为svn文件默认是excludes,所以要设置一下)
<delete defaultexcludes="false">
<fileset dir="src" includes="**/*.svn"/>
</delete>

删除文件目录树
<deltree dir="dist"/>

6.5,剪切文件

<move todir="some/new/dir">
<fileset dir="my/src/dir">
   <include name="**/*.jar">
   <exclude name="**/ant.jar/>
</fileset>
</move>

6.6重命名

<rename src="ann.jar" dest="ant-${version}.jar/>

6.7建立临时文件

在目录build下,建立名为temp.file,后缀为.xml的文件
<tempfile property="temp.file" destDir="build" suffix=".xml"/>

6.8,Touch的使用

如果文件不存在创建文件,如果存在,更改最后访问时间为当前系统时间
<touch file="myfile"/>

如果文件不存在创建文件,更改最后访问时间为06/28/2002 2:02 pm
<touch datetime="09/10/1974 4:30 pm">
<fileset dir="src_dir"/>
</touch>

6.9,Condition的使用

有<ant>,<or>,<not>等tag

<condition property="isMacOsButNotMacOsX">
<and>
   <os family="mac"/>
   <not>
    <os family="unix"/>
   </not>
</ant>
</condition>

6.10,替换replace

<replace file="configure.sh" value="defaultvalue" propertyFile="source/name.properties">
<replacefilter token="@token1@"/>
<replacefilter token="@token2@" value="value2"/>
<replacefilter token="@token2@" value="property.key"/>
</replace>

6.11,调用chmod

<chmod perm="go-rwx" type="file">
<fileset dir="/web">
   <include name="**/*.cgi"/>
   <include name="**/*.old"/>
</fileset>
<dirset dir="/web">
   <include name="**/private_*"/>
</dirset>
</chmod>

6.12,checksum MD5运算

md5文件,然后把值放入ann.bar.MD5属性
<checksum file="ann.bar"/>

md5文件,然后把值放入annbarMD5属性
<checksum file="ann.bar" property="annbarMD5"/>

md5目录下的所有文件,然后建立一个.md5文件,把所有的md5值放入
<checksum>
<fileset dir=".">
   <include name="ann*"/>
</fileset>
</checksum>

6.13,Available的使用

如果类存在,则设置属性Myclass.present为true,如果没有就false
<available classname="org.whatever.Myclass" property="Myclass.present"/>

如果文件存在则设置属性jaxp.jar.persent为true,否则为false
<property name="jaxp.jar" value="./lib/jaxp11/jaxp.jar"/>
<available file="${jaxp.jar}" property="jaxp.jar.present"/>

如果目录存在,则设置属性为true,否则为false
<available file="/usr/local/lib" type="dir" property="local.lib.present"/>

如果classpath下寻找class,存在则设置属性为true,否则为false
在工程tag下定义path,在target中使用
<property name="jaxp.jar" value="./lib/jaxp11/jaxp.jar"/>
<path id="jaxp" location="${jaxp.jar}"/>
<available classname="javax.xml.transform.Transformer" classpathref="jaxp" property="jaxp11.present"/>

如果在classpath下发现文件则设置属性为true,否则为false
<available property="hava.extras" resource="extratasks.properties">
<classpath>
   <pathelement location="/usr/local/ant/extra.jar"/>
</classpath>
</available>

6.14,设置property

设置属性name-value
<property name="ann.dist" value="dist"/>

读取属性文件中的属性配置
<property file="ann.properties"/>

读取网络中的property-set
<property url="http://www.mysite.com/bla/props/ann.properties"/>

读取文件中的属性配置
<property resource="ann.properties"/>

读取环境变量
<property environment="env"/>

读取属性文件中的属性,并作为全局引用
<property file="/Users/antoine/.ant-golbal.properties"/>

6.15,错误处理

显示错误:
1,<fail>something wrong here.</fail>
2,<fail message="${属性}"/>

如果这个属性不存在显示错误:
<fail unless="failCondition" message="unless Condition"/>

如果这个属性存在显示错误
<fail if="failCondition" message="if Condition"/>

如果符合条件显示错误,(这里的条件是没有设置属性):
<fail message="tag condition">
<condition>
   <not>
    <isset property="failCondition"/>
   </not>
</condition>
</fail>

6.16,建立一个目录

<mkdir dir="${dist}/lib"/>

6.17,打jar包

<jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/>
或者
<jar destfile="${dist}/lib/app.jar" basedir="${build}/classes" includes="mypackage/test/**" excludes="**/Test.class"/>

6.18,打Ear包

<ear destfile="build/myapp.ear" appxml="src/metadata/application.xml">
<fileset dir="build" includes="*.jar,*.war"/>
</ear>

6.19,执行程序

<target name="help">
<exec executable="cmd">
   <arg value="/c"/>
   <arg value="ant.bat"/>
   <arg value="-p"/>
</exec>
</target>

6.20,运行jar包

带参数执行:
<java classname="test.Main">
<arg value="-h"/>
<classpath>
   <pathelement loc ...

posted @ 2008-10-31 19:34  Earl_86  阅读(1898)  评论(0编辑  收藏  举报