无所不能的Ant 【转】
一.Ant简介:
二.介绍Ant的DATATYPE和特性
1.路径(Path)
<classpath>
<pathelement location =”lib/some.jar”/>
</classpath>
<classpath>
<pathelement path =”build/classes;lib/some.jar”/>
</classpath>
2.文件集(Fileset)
<copy todir=”new_web”>
<fileset dir=”web”/>
</copy>
<fileset>
<include name="**/*Test.java"/>
</fileset>
<fileset>
<exclude name="**/*.jsp"/>
</fileset>
3.模式集(Patternset)
4.选择器(Selector)
<copy todir="newfiles">
<fileset dir="web">
<not>
<present targetdir="currebtfiles"/>
</not>
</fileset>
</copy>
<copy todir="newfiles">
<fileset dir="web">
<contains text="System"/>
</fileset>
四.使用Ant进行Junit测试
我们除了使用java来直接运行junit之外,我们还可以使用junit提供的junit task与ant结合来运行。涉及的几个主要的ant task如下:
l <junit>,定义一个junit task
l <batchtest>,位于<junit>中,运行多个TestCase
l <test>,位于<junit>中,运行单个TestCase
l <formatter>,位于<junit>中,定义一个测试结果输出格式
l <junitreport>,定义一个junitreport task
l <report>,位于<junitreport>中,输出一个junit report
运行Junit需要jakarta-ant-1.4-optional.jar和Junit.jar包,因为这两个包用于支持ant task--<junit>的,所以不能在build.xml文件中加载,需要将他们放到ANT_HOME中去.使用eclipse可以按照一下步骤加入:
Windows-Preference-Ant-Runtime-Ant Home Entries
下面看一个Junit测试的例子:
<?xml version="1.0"?>
<project name="project" default="junit">
<property name="run.classpath" value="bin"></property>
<property name="run.srcpath" value="src"></property>
<property name="test.srcpath" value="test"></property>
<property name="lib.dir" value="lib"/>
<path id="compile.path">
<pathelement location="${lib.dir}/junit-3.8.1.jar"/>
<pathelement location="${lib.dir}/log4j-1.2.8.jar"/>
</path>
<target name="compile">
<javac destdir="${run.classpath}" srcdir="${run.srcpath}"
classpathref="compile.path"/>
<javac destdir="${run.classpath}" srcdir="${test.srcpath}"
classpathref="compile.path"/>
</target>
<target name="junit" depends="compile">
<junit printsummary="true">
<classpath path="${run.classpath}"></classpath>
<test name="org.ant.test.Test1"></test>
</junit>
</target>
</project>
|
可以看出Junit的使用基本和java差不多, printsummary允许输出junit信息,当然Ant提供formatter属性支持多样化的junit信息输出.Ant包含三种形式的formatter:
brief:以文本格式提供测试失败的详细内容;
plain:以文本格式提供测试失败的详细内容以及每个测试的运行统计;
xml:以xml格式提供扩展的详细内容,包括正在测试时的Ant特性,系统输出,以及每个测试用 例的系统错误.
使用formatter时建议将printsummary关闭,因为他可能对formatter的生成结果产生影响,并多生成一份同样的输出.当然我们可以使用formatter将输出结果显示在console中:
<formatter type="brief" usefile="false"/>
Junit支持多个formatter同时存在:
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
使用xml我们可以得到扩展性更强的信息输出,这时在<test>中要设定todir来指定xml的输出路径.
在通常情况下我们不可能一个一个来处理junit,所以Ant提供了<batchtest>,可以在他里面嵌套文件集(fileset)以包含全部的测试用例.
对于大量的用例,使用控制台输出,或者使用文件或xml文件来作为测试结果都是不合适的,Ant提供了<junitreport>任务使用XSLT将xml文件转换为HTML报告.该任务首先将生成的XML文件整合成单一的XML文件,然后再对他进行转换,这个整合的文件默认情况下被命名为:TESTS-TestSuites.xml.
<junitreport todir="${test.xml}">
<fileset dir="${test.xml}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${test.report}"/>
</junitreport>
|
<report>元素指示转换过程中生成有框架(frames)或者无框架的类似与javadoc格式的文件,并保存到todir所在的目录下面.(由于xalan对于JDK1.4以上的版本存在问题,所以要生成HTML文件需要以下步骤:现在最新的xalan,在%JAVA_HOME%/jre/lib中建立文件夹endorsed.将xalan中的jar文件copy到里面).
下面看一个完整的例子:
<?xml version="1.0"?>
<projectname="project"default="junit">
<propertyname="run.classpath"value="bin"></property>
<propertyname="run.srcpath"value="src"></property>
<propertyname="test.srcpath"value="test"></property>
<propertyname="test.xml"value="xml"></property>
<propertyname="test.report"value="report"></property>
<propertyname="lib.dir"value="lib"/>
<pathid="compile.path">
<pathelementlocation="${lib.dir}/junit-3.8.1.jar"/>
<pathelementlocation="${lib.dir}/log4j-1.2.8.jar"/>
</path>
<targetname="init">
<deletedir="${test.report}"/>
<mkdirdir="${test.report}"/>
<deletedir="${test.xml}"/>
<mkdirdir="${test.xml}"/>
</target>
<targetname="compile"depends="init">
<javacdestdir="${run.classpath}"srcdir="${run.srcpath}"
classpathref="compile.path"/>
<javacdestdir="${run.classpath}"srcdir="${test.srcpath}"
classpathref="compile.path"/>
</target>
<targetname="junit"depends="compile">
<junitprintsummary="false">
<classpathpath="${run.classpath}"></classpath>
<formattertype="xml"/>
<batchtesttodir="${test.xml}">
<filesetdir="${run.classpath}">
<includename="**/Test*.class"/>
</fileset>
</batchtest>
</junit>
<junitreporttodir="${test.xml}">
<filesetdir="${test.xml}">
<includename="TEST-*.xml"/>
</fileset>
<reportformat="frames"todir="${test.report}"/>
</junitreport>
</target>
</project>
<?xml version="1.0"?>
<projectname="project"default="junit">
<propertyname="run.classpath"value="bin"></property>
<propertyname="run.srcpath"value="src"></property>
<propertyname="test.srcpath"value="test"></property>
<propertyname="test.xml"value="xml"></property>
<propertyname="test.report"value="report"></property>
<propertyname="lib.dir"value="lib"/>
<pathid="compile.path">
<pathelementlocation="${lib.dir}/junit-3.8.1.jar"/>
<pathelementlocation="${lib.dir}/log4j-1.2.8.jar"/>
</path>
<targetname="init">
<deletedir="${test.report}"/>
<mkdirdir="${test.report}"/>
<deletedir="${test.xml}"/>
<mkdirdir="${test.xml}"/>
</target>
<targetname="compile"depends="init">
<javacdestdir="${run.classpath}"srcdir="${run.srcpath}"
classpathref="compile.path"/>
<javacdestdir="${run.classpath}"srcdir="${test.srcpath}"
classpathref="compile.path"/>
</target>
<targetname="junit"depends="compile">
<junitprintsummary="false">
<classpathpath="${run.classpath}"></classpath>
<formattertype="xml"/>
<batchtesttodir="${test.xml}">
<filesetdir="${run.classpath}">
<includename="**/Test*.class"/>
</fileset>
</batchtest>
</junit>
<junitreporttodir="${test.xml}">
<filesetdir="${test.xml}">
<includename="TEST-*.xml"/>
</fileset>
<reportformat="frames"todir="${test.report}"/>
</junitreport>
</target>
</project>
|
生成的文档:
点击Properties超链接会弹出一个窗口显示在测试运行时全部的Ant特性,这对于跟踪由环境和配置造成的失败是非常便利的!
五.使用Ant运行本地程序
1.使用Ant运行windows的批处理文件
要在Ant内运行一个外部程序,应使用<exec>任务.它允许你执行下列操作:
l 指定程序名和要传入的参数.
l 命名运行目录.
l 使用failonerror标志来控制当应用程序失败时是否停止构建.
l 指定一个最大程序持续时间,时间超过则中止程序.任务在这时被认为是失败,但是至少构建会中止,而不是挂起,这对于自动构建是至关重要的.
l 将输出存到一个文件或特性.
l 指定java调用本地程序时需要预先设定的环境变量.
下面来看一个例子:
批处理文件:
Test.bat
@echo off
echo Hello > test.txt
|
build.xml
<?xml version="1.0"?>
<project name="batch" default="extract" basedir=".">
<target name="extract">
<exec executable ="cmd">
<arg line="/c a.bat"/>
</exec>
</target>
</project>
|
使用executable元素标记指定使用的命令,具体用法可以在命令行下面输入help cmd查看.如果你希望在运行批处理发生错误时中止构建需要设定failonerror="on".加入你的外部程序在某个时刻挂起,也许是在与远程站点对话,而你不希望构建永远被挂起,Ant提供了timeout这个属性,他是一个以毫秒为单位的数字.下面看一下如何使用Ant来运行tomcat.
启动tomcat需要两个环境变量CATALINA_HOME, JAVA_HOME,如果你在环境变量中已经设定,在Ant中就不需要进行处理,如果没有需要使用<env>属性来设定,你也可以使用<env>属性覆盖你以前的环境变量.
<?xml version="1.0"?>
<projectname="batch"default="tomcat-start"basedir=".">
<propertyname="tomcat.dir"value="C:/Tomcat5"></property>
<targetname="tomcat-start">
<execdir="${tomcat.dir}/bin"executable="cmd">
<envkey="CATALINA_HOME"path="${tomcat.dir}"/>
<argvalue="/C startup.bat"/>
</exec>
</target>
</project>
|
2.使用Ant运行shell文件
由于windowsXP的cmd默认没有安装ps,bash等命令,所以我们需要借助的三方的软件来实现这个功能,这里使用cgywin,将cgywin的bin目录加到环境变量的Path里面(下面使用Ant运行cvs也会用到).
<?xml version="1.0"?>
<projectname="batch"default="shell"basedir=".">
<propertyname="tomcat.dir"value="C:/Tomcat5"></property>
<targetname="shell">
<execdir="${tomcat.dir}/bin"executable="bash">
<envkey="CATALINA_HOME"path="${tomcat.dir}"/>
<argvalue="startup.sh"/>
</exec>
</target>
</project>
|
3.使用Ant运行cvs
Ant内置cvs属性,可以很方便的使用cvs:
<?xml version="1.0"?>
<projectname="batch"default="shell"basedir=".">
<propertyname="cvs.root"value="..."></property>
<targetname="cvs">
<cvscvsroot="cvs.root"command="checkout ../.."/>
</target>
</project>
|
如果你的Documents and Settings中有.cvspass文件,那么可以不用设定cvsroot,Ant会自动寻找.
六.工程的打包部署
工程的打包,主要就是文件的操作,下面通过例子简单介绍一下文件的移动,复制和删除.
<?xml version="1.0"?>
<projectname="project"default="jar">
<targetname="copy">
<tstamp>
<formatproperty="time.format" pattern="yyyy-mm-dd'T'HH:mm:ss"
locale="en"/>
</tstamp>
<copytofile="dist/readme"file="test.txt">
<filterset>
<filtertoken="TIME"value="${time.format}"/>
</filterset>
</copy>
</target>
<targetname="move">
<movetodir="dist">
<filesetdir="lib">
<includename="*.jar"/>
</fileset>
</move>
</target>
<targetname="delete"depends="copy,move">
<deleteverbose="true"failonerror="false">
<filesetdir="dist">
<includename="*.jar"/>
</fileset>
</delete>
</target>
</project>
|
需要说明的是文件删除的时候可能这个文件正在被别人是用而无法删除,所以要用failonerror来标记,文件的复制是时间戳敏感的,如果拷贝的文件比原文件要老,那么Ant将不会执行copy,解决的办法是将overwrite属性设置为true,由于移动文件是复制文件的一个子类,所以它们的原理基本相同.
前面已经例举过一个jar文件打包的例子,下面主要介绍war文件的打包.Ant提供war文件打包的属性.<war>任务是<jar>任务的子类,但是他也提供了一些特有的属性:
<targetname="deploy"depends="init">
<wardestfile="${war.dir}/spring.war"webxml="${web.dir}/web.xml">
<classesdir="${web.dir}/classes"></classes>
<filesetdir="WebContent"excludes="web.xml"></fileset>
<libdir="${web.dir}/lib"></lib>
</war>
</target>
|
可以看出war任务提供了许多WEB应用程序的特有属性,只要你指定了这些文件,war任务就会自动将他们放到正确的位置.
部署是项目发布的过程,Ant支持FTP,Email,本地和远程等几种部署模式,但是Ant并不内置对一些部署的支持,需要第三方的库.
optional.jar 也可能是这样的名字: jakarta-ant-1.4.1.optional.jar
netcomponents.jar <ftp>和<telnet>需要
activation.jar <mail>需要
mail.jar <mail>需要
下面只以本地部署为例,服务器为tomcat.
由于tomcat支持热部署,可以将webapp文件下的war文件自解压缩,所以最简单的部署方式是将工程打成war包后直接copy到webapp目录下面.另一种方法是使用tomcat的管理员身份,在manager页面装载和删除应用,这种方法比较复杂,也比较正规,他也是远程部署的基础.
<?xml version="1.0"?>
<project name="project" default="deploy-local-catalina">
<property name="war.dir" value="dist"></property>
<property name="web.dir" value="WebContent/WEB-INF"></property>
<property name="webapp.name" value="spring"></property>
<property name="catalina.port" value="8080"></property>
<property name="catalina.username" value="admin"></property>
<property name="catalina.password" value="admin"></property>
<target name="init">
<mkdir dir="${war.dir}"/>
</target>
<target name="mkwar" depends="init">
<war destfile="${war.dir}/spring.war" webxml="${web.dir}/web.xml" >
<classes dir="${web.dir}/classes"></classes>
<fileset dir="WebContent" excludes="web.xml"></fileset>
<lib dir="${web.dir}/lib"></lib>
</war>
</target>
<target name="remove-local-catalina">
<property name="deploy.local.remove.url"
value="http://localhost:${catalina.port}/manager/remove"></property>
<get dest="deploy.local.remove.txt"
src="${deploy.local.remove.url}?path=/${webapp.name}"
username="admin" password="admin"/>
<loadfile property="depoly.local.remove.result"
srcfile="depoly.local.remove.txt"></loadfile>
</target>
<target name="deploy-local-catalina" depends="mkwar, remove-local-catalina">
<property name="deploy.local.urlpath"
value="file:///D:/MyEclipse/workspace/springstruts/dist/spring.war"></property>
<property name="deploy.local.url.params"
value="path=/${webapp.name}&war=${deploy.local.urlpath}"></property>
<property name="deploy.local.url"
value="http://localhost:${catalina.port}/manager/install"></property>
<get src="${deploy.local.url}?${deploy.local.url.params}"
dest="deploy-local.txt"
username="admin"
password="admin"/>
<loadfile property="deploy.local.result"
srcfile="deploy-local.txt"></loadfile>
</target>
</project>
|
可以看出只要将上面的localhost换成目标的ip地址就可以实现tomcat的远程部署