1:下载和安装
下载地址:http://ant.apache.org/
添加系统环境变量:ANT_HOME 指向ANT的安装目录
添加path路径。
2:ant的关键元素
2.1 project元素
project元素是Ant构件文件的根元素,Ant构件文件至少应该包含一个project元素,
否则会发生错误。在每个project元素下,可包含多个target元素。接下来向读者展示一下project元素的各属性。
1) name属性
用于指定project元素的名称。
2) default属性
用于指定project默认执行时所执行的target的名称。
3) basedir属性
用于指定基路径的位置。该属性没有指定时,使用Ant的构件文件的附目录作为基准目录。
例子:
<?xml version="1.0"?>
<project name="projectStudy" default="sayBaseDir" basedir="E:\apache-ant-1.7.0">
<target name="sayBaseDir">
<echo message="The base dir is: ${basedir}"/>
</target>
</project>
2.2 target元素
它为Ant的基本执行单元,它可以包含一个或多个具体的任务。多个target可以存在相互依赖关系。它有如下属性:
1) name属性
指定target元素的名称,这个属性在一个project元素中是唯一的。我们可以通过指定target元素的名称来指定某个target。
2) depends属性,
用于描述target之间的依赖关系,若与多个target存在依赖关系时,需要以“,”间隔。Ant会依照depends属性中target出现的顺序依次执行每个target。
被依赖的target会先执行。
3)if属性
用于验证指定的属性是否存在,若不存在,所在target将不会被执行。
4) unless属性
该属性的功能与if属性的功能正好相反,它也用于验证指定的属性是否存在,
若不存在,所在target将会被执行。
5) description属性
该属性是关于target功能的简短描述和说明。
<project name="targetStudy">
<target name="targetA" if="ant.java.version">
<echo message="Java Version: ${ant.java.version}"/>
</target>
<target name="targetB" depends="targetA" unless="amigo">
<description>
a depend example!
</description>
<echo message="The base dir is: ${basedir}"/>
</target>
</project>
2.3 property元素
该元素可看作参量或者参数的定义,project的属性可以通过property元素来设定,也可在Ant之外设定。若要在外部引入某文件,
例如build.properties文件,可以通过如下内容将其引入:<property file=” build.properties”/>
property元素可用作task的属性值。在task中是通过将属性名放在“${”和“}”之间,并放在task属性值的位置来实现的。
Ant提供了一些内置的属性,它能得到的系统属性的列表与Java文档中System.getPropertis()方法得到的属性一致,这些系统属性可参考sun网站的说明。
同时,Ant还提供了一些它自己的内置属性,如下:
basedir:project基目录的绝对路径,该属性在讲解project元素时有详细说明,不再赘述;
ant.file:buildfile的绝对路径,如上面的各例子中,ant.file的值为E:\build.xml;
ant.version:Ant的版本,在本文中,值为1.7.0;
ant.project.name:当前指定的project的名字,即前文说到的project的name属性的值;
ant.java.version:Ant检测到的JDK的版本,在上例运行结果中可看到为1.5。
<project name="propertyStudy" default="example">
<property name="name" value="amigo"/>
<property name="age" value="25"/>
<target name="example">
<echo message="name: ${name}, age: ${age}"/>
</target>
</project>
2.4 <jar>标签
该标签用来生成一个JAR文件,其属性如下。
(1) destfile表示要生成的JAR文件名。
(2) basedir表示被归档的文件名。
(3) includes表示需要归档的文件模式。
(4) exchudes表示被排除的文件模式。
2.5 <javac标签>
该标签用于编译一个或一组java文件,成class文件,其属性如下。
(1)srcdir表示源程序的目录。
(2)destdir表示class文件的输出目录。
(3)include表示被编译的文件的模式。
(4)excludes表示被排除的文件的模式。
(5)classpath表示所使用的类路径。
(6)debug表示包含的调试信息。
(7)optimize表示是否使用优化。
(8)verbose 表示提供详细的输出信息。
(9)fileonerror表示当碰到错误就自动停止。
2.6 <java>标签
该标签用来执行编译生成的.class文件,其属性如下。
(1)classname 表示将执行的类名。
(2)jar表示包含该类的JAR文件名。
(3)classpath所表示用到的类路径。
(4)fork表示在一个新的虚拟机中运行该类。
(5)failonerror表示当出现错误时自动停止。
(6)output 表示输出文件。
(7)append表示追加或者覆盖默认文件。
2.7 <delete>标签
该标签用于删除一个文件或一组文件,其属性如下。
(1)file表示要删除的文件。
(2)dir表示要删除的目录。
(3)includeEmptyDirs 表示指定是否要删除空目录,默认值是删除。
(4)failonerror 表示指定当碰到错误是否停止,默认值是自动停止。
2.8 <copy>标签
该标签用于文件或文件集的拷贝,其属性如下。
(1)file 表示源文件。
(2)tofile 表示目标文件。
(3)todir 表示目标目录。
(4)overwrite 表示指定是否覆盖目标文件,默认值是不覆盖。
(5)includeEmptyDirs 表示制定是否拷贝空目录,默认值为拷贝。
(6)failonerror 表示指定如目标没有发现是否自动停止,默认值是停止。
如果我们部署一个 web应用的话,经常用到的标签有:delete,mkdir,copy,jar,target,project。
3.Ant的常用任务
在Ant工具中每一个任务封装了具体要执行的功能,是Ant工具的基本执行单位。
3.1 copy任务
该任务主要用来对文件和目录的复制功能。举例如下:
Eg1.复制单个文件:<copy file="file.txt" tofile="copy.txt"/>
Eg2.对文件目录进行复制:
<copy todir="../newdir/dest_dir">
<fileset dir="src_dir"/>
</copy>
Eg3. 将文件复制到另外的目录:
<copy file="file.txt" todir="../other/dir"/>
3.2 delete任务
对文件或目录进行删除,举例如下:
Eg1. 删除某个文件:<delete file="photo/amigo.jpg"/>
Eg2. 删除某个目录:<delete dir="photo"/>
Eg3. 删除所有的备份目录或空目录:
<delete includeEmptyDirs="true">
<fileset dir="." includes="**/*.bak"/>
</delete>
3.3 mkdir任务
创建目录。eg:<mkdir dir="build"/>
3.4 move任务
移动文件或目录,举例如下:
Eg1. 移动单个文件:<move file="fromfile" tofile=”tofile”/>
Eg2. 移动单个文件到另一个目录:<move file="fromfile" todir=”movedir”/>
Eg3. 移动某个目录到另一个目录:
<move todir="newdir">
<fileset dir="olddir"/>
</move>
3.5 echo任务
该任务的作用是根据日志或监控器的级别输出信息。它包括message、file、append和level四个属性,举例如下:
<echo message="Hello,Amigo" file="logs/system.log" append="true">
4.利用Ant构建和部署Java工程
Ant可以代替使用javac、java和jar等命令来执行java操作,从而达到轻松的构建和部署Java工程的目的。下面来看几个知识点。
4.1 利用Ant的javac任务来编译java程序
Ant的javac任务用于实现编译Java程序的功能。下面来看一个简单的例子:
首先我们建立名为antstudy的Java工程,建立src目录为源代码目录,在src目录下建立HelloWorld.java这个类文件。
该类文件的内容如下:
public class HelloWorld {
publicstaticvoid main(String[] args) {
System.out.println("Hello,Amigo");
}
}
同时在antstudy工程的根目录下建立build.xml文件,在该文件中编译src目录下的java文件,
并将编译后的class文件放入build/classes目录中,
在编译前,需清除classes目录,该文件的内容如下:
<?xml version="1.0"?>
<project name="javacTest" default="compile" basedir=".">
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile"depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/>
</target>
</project>
运行该build.xml文件,可在工程中看到新增了build/classes目录,并在该目录中生成了编译后的HelloWorld.class文件。
5.使用Ant的java任务运行Java程序
Ant中可以使用java任务实现运行Java程序的功能。下面在1的例子中进行如下的修改,修改后的build.xml文件的内容如下:
<?xml version="1.0"?>
<projectname="javaTest"default="run"basedir=".">
<targetname="clean">
<deletedir="build"/>
</target>
<targetname="compile"depends="clean">
<mkdirdir="build/classes"/>
<javacsrcdir="src"destdir="build/classes"/>
</target>
<targetname="run"depends="compile">
<javaclassname="HelloWorld">
<classpath>
<pathelementpath="build/classes"/>
</classpath>
</java>
</target>
</project>
运行该build.xml文件,可在控制台看到HelloWorld的main方法的输出。
6.使用Ant的jar任务生成jar文件
读者可以在上例的基础上更进一步,来生成jar包,可在run这个target下再加上如下target:
<?xml version="1.0"?>
<project name="javaTest" default="jar" basedir=".">
<targetname="clean">
<deletedir="build"/>
</target>
<targetname="compile"depends="clean">
<mkdirdir="build/classes"/>
<javac srcdir="src"destdir="build/classes"/>
</target>
<targetname="run"depends="compile">
<java classname="HelloWorld">
<classpath>
<pathelementpath="build/classes"/>
</classpath>
</java>
</target>
<target name="jar"depends="run">
<jar destfile="helloworld.jar" basedir="build/classes">
<manifest>
<attributename="Main-class"value="HelloWorld"/>
</manifest>
</jar>
</target>
</project>
此时将ant的project的default属性设置为jar,同时运行该build.xml文件,运行完毕后,可看到在工程目录下生成了一个jar包HelloWorld.jar。
7.将j2ee web 工程打成jar包
建立一个J2EE Web工程.
其中src为源代码目录,WebRoot为各jsp存放目录,lib为工程的包目录。在demoWeb工程目录下建立了build.xml文件,
该文件为该工程的Ant构件文件。读者可以src目录下放入在前续例子中开发的HelloWorld.java文件,
并在WebRoot下建立index.jsp文件,其内容很简单,就是输出Hello信息,代码如下所示:
---------实例一 -------
<!--去除Myeclipse 的自动编译功能 ,编译(没有第三包参加的编译),部署 -->
<?xml version="1.0" encoding="UTF-8"?>
<!-- J2EE 部署-->
<project name="demoWeb" default="core" basedir=".">
<!-- 原文件路径 -->
<property name="src" value="src"/>
<!-- Class文件路径 -->
<property name="classes" value="WebRoot/WEB-INF/classes"/>
<!-- lib 文件路径 -->
<property name="lib" value="WebRoot/WEB-INF/lib"/>
<!--定义发布成的总路径名-->
<property name="projectWeb" value="demoWeb"/>
<!--定义tomcat所在目录-->
<property name="webapp" value="F:/Program Files/tomcat32/apache-tomcat-6.0.32/webapps/${projectWeb}" />
<!-- 删除classes路径-->
<target name="clean">
<delete dir="classes"/>
</target>
<!-- 建立${classes}路径,并编译class文件到${classes}路径下-->
<target name="compile" depends="clean">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}"/>
</target>
<!-- 将编译后的WEB功能,发布到${webapp} -->
<target name="core" depends="compile">
<!--删除原来部署的文件-->
<delete dir="${webapp}"></delete>
<!--创建新的部署文件-->
<mkdir dir="${webapp}" />
<!--将编译后的文件拷贝到tomcat目录下-->
<copy todir="${webapp}" overwrite="true">
<fileset dir="WebRoot"/>
</copy>
</target>
</project>
---------实例二 -------
<?xml version="1.0" encoding="UTF-8"?>
<!--去除Myeclipse 的自动编译功能 ,编译,部署,重启Tomcat应用服务(重启服务的方法比较简单) -->
<project name="demoWeb" default="reload" basedir=".">
<property name="webapp.name" value="demoWeb"/>
<property name="catalina.home" value="F:/Program Files/tomcat32/apache-tomcat-6.0.32"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="lib.dir" value="${basedir}/WebRoot/WEB-INF/lib"/>
<property name="class.dir" value="${basedir}/WebRoot/WEB-INF/classes"/>
<property name="webRoot.dir" value="${basedir}/WebRoot" />
<property name="webapps.dir" value="${catalina.home}/webapps"/>
<property name="javahome.dir" value="F:/Program Files (x86)/Java/jdk1.6.0_29"/>
<!-- **********************************set classpath********************************** -->
<path id="compile.classpath">
<fileset dir="${catalina.home}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<!-- **********************************init********************************** -->
<target name="init">
<mkdir dir="${src.dir}"/>
<mkdir dir="${lib.dir}"/>
</target>
<!-- **********************************clean class********************************** -->
<target name="clean" description="Delete old build and dist directories">
<delete dir="${class.dir}" includes="**/*.class"/>
</target>
<!-- **********************************compile java********************************** -->
<target name="compile" description="Compile Java sources" depends="clean">
<mkdir dir="${class.dir}"/>
<javac srcdir="${src.dir}" destdir="${class.dir}">
<classpath refid="compile.classpath"/>
</javac>
<copy todir="${class.dir}">
<fileset dir="${src.dir}" excludes="**/*.java"/>
</copy>
</target>
<!-- **********************************deploy webapp********************************** -->
<target name="deploy" description="Install application to servlet container" depends="compile">
<delete dir="${webapps.dir}/${webapp.name}"/>
<!-- 打War包 -->
<!--
<war destfile="${webapps.dir}/${webapp.name}.war" webxml="${basedir}/WebRoot/WEB-INF/web.xml">
<lib dir="${lib.dir}"/>
<classes dir="${class.dir}"/>
</war>
-->
<!--copy应用的目录到tomcat的webapps下-->
<copy todir="${webapps.dir}/${webapp.name}" >
<fileset dir="${webRoot.dir}"></fileset>
</copy>
</target>
<!-- **********************************start web server********************************** -->
<target name="startserver" description="Start web server" >
<exec dir="${catalina.home}/bin" executable="cmd.exe">
<env key="CATALINA_HOME" path="${catalina.home}"/>
<env key="JAVA_HOME" path="${javahome.dir}"/>
<arg value="/c startup.bat"/>
</exec>
</target>
<!-- **********************************stop web server********************************** -->
<target name="stopserver" description="Stop web server" >
<exec dir="${catalina.home}/bin" executable="cmd.exe">
<env key="CATALINA_HOME" path="${catalina.home}"/>
<env key="JAVA_HOME" path="${javahome.dir}"/>
<arg value="/c shutdown.bat"/>
</exec>
</target>
<!-- **********************************start work********************************** -->
<target name="start" description="Clean build and dist directories, then compile">
<ant target="deploy"/>
<ant target="startserver"/>
</target>
<!-- **********************************reload web server********************************** -->
<target name="reload" description="reload web server" depends="deploy">
<ant target="stopserver"></ant>
<sleep seconds="2"></sleep>
<ant target="start"></ant>
</target>
</project>
---------实例三 -------
<!--包含了Myeclipse 的自动编译功能 ,部署,重启Tomcat应用服务(重启服务比较复杂,还包含有DEBUG模式) -->
<?xml version="1.0" encoding="UTF-8"?>
<!--去除Myeclipse 的自动编译功能 -->
<project name="SMOP" default="start" basedir=".">
<property name="webapp.name" value="SMOP"/>
<property name="catalina.home" value="F:/Program Files/tomcat32/apache-tomcat-6.0.32"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="lib.dir" value="${basedir}/WebRoot/WEB-INF/lib"/>
<property name="class.dir" value="${basedir}/WebRoot/WEB-INF/classes"/>
<property name="webRoot.dir" value="${basedir}/WebRoot" />
<property name="webapps.dir" value="${catalina.home}/webapps"/>
<property name="javahome.dir" value="F:/Program Files (x86)/Java/jdk1.6.0_29"/>
<property name="javac.dir" value="F:/Program Files (x86)/Java/jdk1.6.0_29/bin/javac"/>
<!-- ********** set classpath ********** -->
<path id="compile.classpath">
<fileset dir="${catalina.home}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<!-- ********** init ********** -->
<target name="init">
<mkdir dir="${src.dir}"/>
<mkdir dir="${lib.dir}"/>
</target>
<!-- ********** clean class ********** -->
<target name="clean" description="Delete old build and dist directories">
<delete dir="${class.dir}" includes="**/*.class"/>
</target>
<!-- ********** compile java ********** -->
<target name="compile" description="Compile Java sources" depends="clean">
<mkdir dir="${class.dir}"/>
<javac fork="true" executable="${javac.dir}" encoding="UTF-8" srcdir="${src.dir}" destdir="${class.dir}">
<classpath refid="compile.classpath"/>
</javac>
<copy todir="${class.dir}">
<fileset dir="${src.dir}" excludes="**/*.java"/>
</copy>
</target>
<!-- ********** deploy webapp ********** -->
<target name="deploy" description="Install application to servlet container">
<delete dir="${webapps.dir}/${webapp.name}"/>
<!-- 打War包 -->
<!--
<war destfile="${webapps.dir}/${webapp.name}.war" webxml="${basedir}/WebRoot/WEB-INF/web.xml">
<lib dir="${lib.dir}"/>
<classes dir="${class.dir}"/>
</war>
-->
<!--copy应用的目录到tomcat的webapps下-->
<copy todir="${webapps.dir}/${webapp.name}" >
<fileset dir="${webRoot.dir}"></fileset>
</copy>
</target>
<!-- ********** start web server method 2 ********** -->
<target name="tomcat.start" description="start web server">
<java jar="${catalina.home}/bin/bootstrap.jar" fork="true">
<jvmarg value="-Dcatalina.home=${catalina.home}"/>
</java>
</target>
<!-- ********stop web server method 2********-->
<target name="tomcat.stop" description="Stop web server">
<java jar="${catalina.home}/bin/bootstrap.jar" fork="true">
<jvmarg value="-Dcatalina.home=${catalina.home}"/>
<arg line="stop"/>
</java>
</target>
<!--******************* debug startup server ***************-->
<target name="tomcat.debug" description="debug startup server">
<java jar="${catalina.home}/bin/bootstrap.jar" fork="true">
<jvmarg value="-Dcatalina.home=${catalina.home}"/>
<jvmarg value="-Xdebug"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"/>
</java>
</target>
<!-- ********************** reload web server method 2 *********** -->
<target name="tomcat.reload" description="reload web server" depends="deploy">
<ant target="tomcat.stop"></ant>
<sleep seconds="2"></sleep>
<ant target="tomcat.debug"></ant>
</target>
<!-- *********************** start work ********************* -->
<target name="start" description="Clean build and dist directories, then compile">
<ant target="deploy"/>
<ant target="tomcat.debug"/>
</target>
</project>
---------实例四-------
<!-- 包含了测试,以及产生文档的方法--->
<?xml version="1.0"?>
<project name="Hello world" default="doc">
<!-- properies -->
<property name="src.dir" value="src" />
<property name="report.dir" value="report" />
<property name="classes.dir" value="classes" />
<property name="lib.dir" value="lib" />
<property name="dist.dir" value="dist" />
<property name="doc.dir" value="doc"/>
<!-- 定义classpath -->
<path id="master-classpath">
<fileset file="${lib.dir}/*.jar" />
<pathelement path="${classes.dir}"/>
</path>
<!-- 初始化任务 -->
<target name="init">
</target>
<!-- 编译 -->
<target name="compile" depends="init" description="compile the source files">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4">
<classpath refid="master-classpath"/>
</javac>
</target>
<!-- 测试 -->
<target name="test" depends="compile" description="run junit test">
<mkdir dir="${report.dir}"/>
<junit printsummary="on"
haltonfailure="false"
failureproperty="tests.failed"
showoutput="true">
<classpath refid="master-classpath" />
<formatter type="plain"/>
<batchtest todir="${report.dir}">
<fileset dir="${classes.dir}">
<include name="**/*Test.*"/>
</fileset>
</batchtest>
</junit>
<fail if="tests.failed">
***********************************************************
**** One or more tests failed! Check the output ... ****
***********************************************************
</fail>
</target>
<!-- 打包成jar -->
<target name="pack" depends="test" description="make .jar file">
<mkdir dir="${dist.dir}" />
<jar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}">
<exclude name="**/*Test.*" />
<exclude name="**/Test*.*" />
</jar>
</target>
<!-- 输出api文档 -->
<target name="doc" depends="pack" description="create api doc">
<mkdir dir="${doc.dir}" />
<javadoc destdir="${doc.dir}"
author="true"
version="true"
use="true"
windowtitle="Test API">
<packageset dir="${src.dir}" defaultexcludes="yes">
<include name="example/**" />
</packageset>
<doctitle><![CDATA[<h1>Hello, test</h1>]]></doctitle>
<bottom><![CDATA[<i>All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:" />
</javadoc>
</target>
</project>
--------常出现的异常------------
问题一:
用Ant编译时报如下错误:
compile:
[javac] Compiling 1 source file to D:\workspace\cwk\build\classes
[javac] D:\workspace\cwk\src\core\com\cwk\core\web\action\LoginController.java:1: 非法字符: \65279
[javac] ?package com.cwk.core.web.action;
[javac] ^
[javac] 1 错误
BUILD FAILED
解决方法:
一般用UE或记事本编辑过的UTF-8的文件头会加入BOM标识,该标识由3个char组成。在UTF-8的标准里该BOM标识是可有可无的,
Sun 的javac 在编译带有BOM的UTF-8的格式的文件时会出现“非法字符:\65279”的错误,但是用Eclipse进行编译却没有问题,
原因在于Eclipse使用的是自己的JDT,而非javac,关于JDT的描述可以到eclipse的官网上去查看。
出现这种情况时,有三种解决方法:
a) 利用UE、Editplus等文本编辑器重新保存文件为不带BOM的UTF-8格式
b) 可使用eclipse自带的编译器进行编译
<!--在ant中添加property,使用eclipse jdt compiler编译-->
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />
相关jar包,在eclipse安装文件plugins目录下:org.eclipse.jdt.core_xxx.jar,xxx为版本号
c) 使用EClipse的自动编译。发布过程使用以上的实例三