到官方主页http://ant.apache.org下载,windows下选择zip格式进行下载
(需要提前安装jdk,并配置有关jdk的环境变量)
JAVA_HOME = C:\Java\jdk1.6.0_21(指java的安装目录,tomcat会从这里找java)
PATH = %JAVA_HOME%\bin;(指的是系统查找执行文件的位置,如果你想直接在命令行中运行某个项目,那么这个东西就必须在path目录里)
CLASSPATH = .;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar(指的是java程序自动查找class的位置,如果在命令行中发现找不到某class,那么就需要考虑这个环境变量了)
Linux平台环境变量的配置大同小异,例如分隔符使用"/"
二、配置环境变量
window中设置ant环境变量:
ANT_HOME C:/ apache-ant-1.8.1(在系统变量中增加)
path C:/ apache-ant-1.8.1/bin(windows下是在已有的Administrator下的path环境变量后追加)
classpath C:/apache-ant-1.8.1/lib
注意:【如:ANT_HOME:C:\apache-ant-1.8.1
PATH:%ANT_HOME%\bin (为了方便在dos环境下操作)
三、验证ant
为了验证ant是否成功安装,可以进行如下操作:
依次选择:开始->运行->cmd,输入如下命令:ant
如果出现如下内容,说明安装成功:
Buildfile: build.xml does not exist!
Build failed
【说明ant安装成功!因为ant默认运行build.xml文件,这个文件需要我们建立。】
查看版本:ant -version
但如果出现如下内容,说明安装成功:(可以重复前述步骤,直至安装成功。)
查看帮助信息:ant -help
'ant' 不是内部或外部命令,也不是可运行的程序或批处理文件。
从别处移动过来的:
使用:
(1)在D盘根目录下建立build.xml
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
2
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
3
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
4
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
5
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
6
![](https://i-blog.csdnimg.cn/blog_migrate/17c135a2763225eb253f4ff92e88a664.gif)
(2)在D盘根目录下建立文件a.txt。
(3)进入dos,
d:
ant
此时可在E:/Temp目录下见到文件aa.txt,内容与a.txt一样,即拷贝成功!(需要cd到包含build.xml的目录)
如果中间提示类似如下错误:
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
这是因为JDK 的安装有问题或者是 JAVA_HOME 环境变量没有设置或者设置有问题, jre下肯定没tools.jar。
例子:
<?xml version="1.0"?><project name="antPro" default="getBaseDir" basedir="C:/ThinkInJavaCode">
<target name="getBaseDir">
<echo message="The base dir is:${basedir}"/>
</target>
</project>
进入C:/ThinkInJavaCode后运行ant命令,得到的结果为:
Buildfile:C:\ThinkInJavaCode\build.xml
sayBaseDir:
[echo] The base dir is:C:ThinkInJavaCode
BUILD SUCCESSFUL
Toal time:0 seconds
四、建立build.xml
用ant编译规模较大的工程非常方便,每个工程都对应一个build.xml文件,这个文件包含与这个工程有关的路径信息和任务,下面给出一个例子
<?xml version="1.0" encoding="UTF-8"?>
<project name="dev" basedir="." default="dist">
<target name="init">
<property name="app.name" value="Chess"/>
<property name="app.vendor" value="Nokia"/>
<property name="app.midlet" value="GameMIDlet"/>
<property name="app.project" value="antdemo"/>
<property name="app.description" value="A demo for ant development"/>
<property name="app.price" value="10"/>
<property name="LIB_PATH" value="../lib"/>
<property name="compile.classpath" value="${LIB_PATH}/nokia60.zip"/>
<property name="proguard.classpath" value="${LIB_PATH}/proguard.jar;${compile.classpath}"/>
</target>
<target name="clean" depends="init">
<mkdir dir="dist"/>
<delete file="dist/${app.project}.jad"/>
<delete file="dist/${app.project}.jar"/>
<delete file="temp"/>
</target>
<target name="compile" depends="clean">
<mkdir dir="temp/classes"/>
<javac srcdir="src" destdir="temp/classes" bootclasspath="${compile.classpath}" target="1.1" encoding="UTF-8"/>
</target>
<target name="obfuscate" depends="compile">
<jar jarfile="temp/${app.project}_tmp.jar" basedir="temp/classes"/>
<java fork="yes" classname="proguard.ProGuard" classpath="${proguard.classpath}">
<arg line="-libraryjars ${proguard.classpath}"/>
<arg line="-injars temp/${app.project}_tmp.jar"/>
<arg line="-outjars temp/${app.project}_obf.jar"/>
<arg line="-defaultpackage '' "/>
<arg line="-dontusemixedcaseclassnames"/>
<arg line="-keep public class ${app.midlet}"/>
<arg line="-overloadaggressively"/>
<arg line="-keepclasseswithmembers public class ${app.midlet} {public void startApp();public void destroyApp(boolean);}"/>
</java>
<mkdir dir="temp/obfuscate"/>
<unjar src="temp/${app.project}_obf.jar" dest="temp/obfuscate"/>
</target>
<target name="preverify" depends="obfuscate">
<mkdir dir="temp/build"/>
<exec executable="${LIB_PATH}/preverify.exe">
<arg line="-classpath ${compile.classpath} -d temp/build temp/obfuscate"/>
</exec>
</target>
<target name="copyres" depends="preverify">
<mkdir dir="temp/res"/>
<copy todir="temp/res">
<fileset dir="res" includes="manifest.mf,*.png"/>
</copy>
<copy todir="temp/build">
<fileset dir="res" excludes="manifest.mf,project.jad,*.png"/>
</copy>
</target>
<target name="replaceres" depends="copyres">
<replace file="temp/res/manifest.mf" encoding="UTF-8">
<replacefilter token="@NAME@" value="${app.name}"/>
<replacefilter token="@VENDOR@" value="${app.vendor}"/>
<replacefilter token="@MIDLET@" value="${app.midlet}"/>
</replace>
</target>
<target name="pngcrush" depends="replaceres">
<exec executable="${LIB_PATH}/pngcrush.exe">
<arg line="-d temp/build temp/res/*.png"/>
</exec>
</target>
<target name="dist" depends="pngcrush">
<jar jarfile="dist/${app.project}.jar" basedir="temp/build" manifest="temp/res/manifest.mf" manifestencoding="UTF-8"/>
<taskdef name="filesize" classname="ant.FileSizeTask" classpath="${LIB_PATH}/FileSizeTask.jar"/>
<filesize file="dist/${app.project}.jar" property="size"/>
<copy tofile="dist/${app.project}.jad" file="res/project.jad"/>
<replace dir="dist" includes="${app.project}.jad" encoding="UTF-8">
<replacefilter token="@NAME@" value="${app.name}"/>
<replacefilter token="@VENDOR@" value="${app.vendor}"/>
<replacefilter token="@MIDLET@" value="${app.midlet}"/>
<replacefilter token="@JAR@" value="${app.project}"/>
<replacefilter token="@FILESIZE@" value="${size}"/>
<replacefilter token="@DESCRIPTION@" value="${app.description}"/>
<replacefilter token="@PRICE@" value="${app.price}"/>
</replace>
</target>
</project>
解释:每个build.xml文件都包含一个project和至少一个target。target包含任务元素,任务是一段可执行代码,每个任务元素都有一个id属性,以便在文件中引用。property完成设置属性功能,javac完成编译java源文件功能(java源文件放在srcdir指定的文件夹中,生成的.class文件按照package语句组织目录,放在desdir指定的文件夹中。要注意源文件的目录组织要与package语句相一致),war完成打包功能。
project有name、default、basedir三个属性
default是必须的,表示默认的target,运行ant时如果不指定target,则用default指定的target
name指定工程的名字
basedir指定工程的基路径,设置为"."表示build.xml所在的路径;此属性没有指定时,使用ant的build.xml的父目录作为基路径
description:表示项目的描述
property介绍:
property元素可看做变量或者参数的定义(即经常使用的变量),project的属性可以通过property元素来设定,也可在ant之外设定。例如,若要在外部引入某文件(例如build.properties文件)则可以使用:
<property file="build.properties"/>
一个工程的property有名字和值,属性设置后可以在后面引用:
例如声明一个属性<property name="app.project" value="antdemo"/>,则在后面使用的时候src="temp/${app.project}_obf.jar"即为temp/antdemo_obf.jar
<property name="src" location="src"/>设置一个名字为src的属性,值是一个路径,用location标识,如果location内容以/或\或D:\之类开始表示绝对路径,否则表示相对路径,相对于project设置的basedir。如果不适用location而使用path或classpath,则可以设置类的路径,后面引用的时候用id设置的值。
target中的属性介绍:
属性name指定本target的名字,该名字在project中需要唯一(必须)
属性depends表示在执行本target之前必须要执行的target,如果此target需要依赖多个target,则以逗号隔开,ant会根据顺序依次执行
属性if:用于验证指定的属性是否存在,若不存在,所在target将不会被执行
属性unless:该功能与if属性的功能正好相反,它也用于验证指定的属性是否存在,若不存在,所在target将会被执行。
属性description:是关于target功能的简短描述和说明
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
如果执行target D的话,会先执行A,然后执行B,然后执行C,最后执行D
一个target只能被执行一次,即使有多个target依赖于它
task中的属性介绍
一个task是一段可执行的代码
一个task可以有多个属性(如果你愿意的话,可以将其称之为变量)。属性只可能包含对property的引用。这些引用会在task执行前被解析。
下面是Task的一般构造形式:
<name attribute1="value1" attribute2="value2" ... />
这里name是task的名字,attributeN是属性名,valueN是属性值。
有一套内置的(built-in)task,以及一些可选task,但你也可以编写自己的task。
所有的task都有一个task名字属性。Ant用属性值来产生日志信息。
可以给task赋一个id属性:
<taskname id="taskID" ... />
这里taskname是task的名字,而taskID是这个task的唯一标识符。通过这个标识符,你可以在脚本中引用相应的task。例如,在脚本中你可以这样:
<script ... >
task1.setFoo("bar");
</script>
设定某个task实例的foo属性。在另一个task中(用java编写),你可以利用下面的语句存取相应的实例。
project.getReference("task1").
注意1:如果task1还没有运行,就不会被生效(例如:不设定属性),如果你在随后配置它,你所作的一切都会被覆盖。
注意2:未来的Ant版本可能不会兼容这里所提的属性,因为很有可能根本没有task实例,只有proxies。
Path-like Structures
你可以用":"和";"作为分隔符,指定类似PATH和CLASSPATH的引用。Ant会把分隔符转换为当前系统所用的分隔符。
当需要指定类似路径的值时,可以使用嵌套元素。一般的形式是
<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>
location属性指定了相对于project基目录的一个文件和目录,而path属性接受逗号或分号分隔的一个位置列表。path属性一般用作预定义的路径--其他情况下,应该用多个location属性。
为简洁起见,classpath标签支持自己的path和location属性。所以:
<classpath>
<pathelement path="${classpath}"/>
</classpath>
可以被简写作:
<classpath path="${classpath}"/>
也可通过<fileset>元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的。
<classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</classpath>
上面的例子构造了一个路径值包括:${classpath}的路径,跟着lib目录下的所有jar文件,接着是classes目录。
如果你想在多个task中使用相同的path-like structure,你可以用<path>元素定义他们(与target同级),然后通过id属性引用--参考Referencs例子。
path-like structure可能包括对另一个path-like structurede的引用(通过嵌套<path>元素):
<path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>
<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
前面所提的关于<classpath>的简洁写法对于<path>也是有效的,如:
<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
可写成:
<path id="base.path" path="${classpath}"/>
对于上例,如果build.xml放在d\demo\下,则可以利用下面的三种方式进行执行
cd d\demo然后ant
ant -buildfile d\demo\build.xml
ant -buildfile d\demo\build.xml dist
(第二种和第三种效果相同是因为build.xml中指定了default的target为dist,所以最先运行dist(实际上dist指定了depends,则先运行dist所depends的target))
如果执行ant -buildfile d\demo\build.xml compile 则执行名字为compile的target
默认状态下ant是去执行build.xml,但是也可以取其他名字,不过在运行的时候要作为参数传入
ant -buildfile aaa.xml意思即运行aaa.xml文件
ant提供的内置属性:
basedir: project 基目录的绝对路径
ant.file: build.xml的绝对路径
ant.version: Ant的版本信息
ant.project.name: project的名字
ant.java.version: ant检测到的jdk版本
五、ant中常用的命令
1、copy命令
(1)复制单个文件
<copy file="original.txt" tofile="copied.txt"/>
(2)对文件目录进行复制
<copy todir="../dest_dir">
<fileset dir="src_dir"/>
</copy>
(3)将文件复制到另外的目录
<copy file="source.txt" todir="../home/philander"/>
overwrite:表示指定是否覆盖目标文件,默认是不覆盖
includeEmptyDirs:表示制定是否拷贝空目录,默认为拷贝
failonerror:如目标没有发现是否自动停止,默认值是停止
verbose:制定是否显示详细,默认值不显示
2、delete命令
(1)删除某个文件
<delete file="/home/photos/philander.jpg"/>
(2)删除某个目录
<delete dir="/home/photos"/>
(3)删除所有的备份目录或空目录(includeEmptyDirs表示指定是否要删除空目录,默认是删除)
<delete includeEmptyDirs="true">
<fileset dir="." includes="**/*.bak"/>
</delete>
failonerror:表示碰到错误是否停止,默认是自动停止
verbose:是否列出所删除的文件,默认为不列出
3、mkdir命令
<mkdir dir="/home/philander/build/classes"/>
4、move命令
(1)移动单个文件
<move file="sourcefile" tofile="destfile"/>
(2)移动单个文件到另一个目录:
<move file="sourcefile" todir="movedir"/>
(3)移动某个目录到另一个目录
<move todir="newdir">
<fileset dir="olddir"/>
</move>
5、echo命令
<echo message="Hello,ant" file="/home/philander/logs/ant.log" append="true" level="1">
执行该命令后,将生成ant.log文件并在其中显示Hello,ant
6、jar
用来生成一个jar文件
destfile:jar文件的文件名
basedir:被归档的文件名
includes:被归档的文件模式
excludes:被排除的文件模式
7、javac
用于编译一个或一组java文件
srcdir:表示源程序目录
destdir:class文件的输出目录
include:被编译的文件的模式
exclude:被排除的文件的模式
classpath:使用的类路径
debug:包含的调试
optimize:是否使用优化
verbose:提供详细的输出
fileonerror:当碰到错误就自动停止
8、java
用来生成.class文件
classname:将执行的类名
jar:包含该类的jar文件名
classpath:用到的类路径
fork:表示在一个新的虚拟机中运行该类
failonerror:当出现错误时自动停止
output:输出文件
append:追加或覆盖默认文件
六、编译项目时出现过的问题:
1、
'mode' 不是内部或外部命令,也不是可运行的程序或批处理文件。
'explorer' 不是内部或外部命令,也不是可运行的程序或批处理文件。
修改环境变量里的path值,在最前面加上 %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
2、
java.lang.OutOfMemoryError: requested 487424 bytes for card table expans
解决方法1:
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${dest}" debug="true" fork="true" memoryMaximumSize="512m">
<classpath refid="project.class.path"/>
<classpath refid="jspc.class.path"/>
</javac>
</target>
在javac的选项里增加 fork="true" memoryMaximumSize="512m"来加在编译时的内存
解决方法2:
在环境变量中新建JAVA_OPTS,值为: -Xms64m -Xmx512
解决方法3:
如果是用eclipse 开发,在用ant编译web工程时,碰到java.lang.OutOfMemoryError: Java heap space异常
window->preferences->java->installed jres->edit jre
把default vm arguments 的参数设为 -Xms64m -Xmx512
解决方法2是通用的方法,不管是直接用ant编译,还是在eclipse中用ant编译。