Ant是一個用于簡單或複雜Java工程的自動化建構、部署工具,它對于那些具有分布式開發團隊或者相信通過頻繁的建構來進行不間斷內建的公司尤其有用。對于那些建立傳統全Java應用程式以及那些使用HTML、JSP和Java servlets建立Web應用程式的公司來說,Ant極具價值。無論你的Java開發者使用什麼作業系統、內建開發環境或者建構環境,Ant都可以将你的工程集合在一起,用于那些重要的建構。Ant也能夠自動化并且同步文檔部署,這通常發生在軟體開發過程中的沒有正式文檔和文檔比較混亂的部分。
在建構和部署Java應用程式的時候,Ant處理着大量有用的任務。最基本的任務包括添加和移除目錄、使用FTP拷貝和下載下傳檔案、建立JAR和ZIP檔案以及建立文檔。更進階的特性包括用源代碼控制系統諸如CVS或者SourceSafe來檢查源代碼、執行SQL查詢或腳本、将XML檔案轉換為人能識别的HTML,以及為遠端方法調用生成stub(存根)檔案。
Ant和Make(非常著名的建構工具,很多C語言開發人員都使用它)之間有什麼不同?Ant是為Java而建立,帶有屬于其自身的、獨特的範例,具有可移植性。而Make依賴于固定的作業系統指令(是以一個運作在微軟Windows下的Make檔案對于使用UNIX的開發者來說毫無用處),利用Ant建構的純Java工程是可移植的,因為Ant本身就是用Java編寫的,并且Ant bulidfiles使用XML文法。
1.下載下傳及安裝
Apache Ant是一個基于Java的建構工具,滿足跨平台使用。
下載下傳及安裝:
http://ant.apache.org/解壓下載下傳的Ant拷貝到任意目錄以D:\Program Files\apache-ant-1.8.4為例
将D:\Program Files\apache-ant-1.8.4配置為系統變量ANT_HOME
在PATH中加入%ANT_HOME%\bin
指令提示符中輸入ant相關指令可以檢視是否配置正确。
2.簡單執行個體
執行個體:編譯運作一個簡單的類。
編寫一個簡單的HelloWorld
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, ANT!!!");
}
}
建立build.xml(名稱可改)
HelloWorld.java和build.xml所在目錄示意:
├src
│ └HelloWorld.java
└build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="antStudyProj" default="run" basedir=".">
<property name="classdir" value="build/classes"/>
<echo message="Learn Ant!!!"/>
<target name="clean">
<delete dir="${classdir}"/>
</target>
<target name="compile" depends="clean">
<mkdir dir="${classdir}" />
<javac srcdir="src" destdir="${classdir}" includeantruntime="false"/>
</target>
<target name="run" depends="compile">
<java classname="HelloWorld">
<classpath path="${classdir}"/>
</java>
</target>
</project>
運作Ant,檢視結果(可以通過ant -help檢視ant指令的使用)
這裡使用ant -buildfile build.xml檔案的絕對路徑來運作,結果如下:
注意:可以通過其他方式也可運作ant,ant的入口為org.apache.tools.ant.launch.Launcher,裡面包含mian方法,可指定執行該類并傳入參數。
3.buildfile介紹
這是官網的build.xml示例
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<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"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
buildfile使用XML編寫。每個buildfile包含一個project元素,而project元素至少有一個target。
project有三個屬性name、default、basedir,都不是必須的。
name:項目名稱
default:指定預設執行的target
basedir:故名思意就是工作的根目錄 .代表目前目錄
project中可以定義多個target。Target是要執行的tasks的集合。
target有以下屬性:name,depends,if,unless,description,extensionOf,onMissingExtensionPoint。
name:target的名字,必須
depends:此target依賴的targets,用逗号隔開,非必須
if:某個屬性存在或表達式的計算結果為true,非必須
unless:和if對應,非必須
description:對target的描述,非必須
task能被執行的一段代碼,結構如下
<name attribute1="value1" attribute2="value2" ... />
Property屬性可以通過name及value定義屬性,或通過file指定載入的屬性檔案等。
當定義了一個name為example的屬性後,可通過${example}進行引用。
<property name="foo.dist" value="dist"/>
将屬性foo.dist的值設定為dist
<property file="foo.properties"/>
從foo.properties檔案中讀取屬性
<property url="http://www.mysite.com/bla/props/foo.properties"/>
從url指定的properties中讀取所有屬性
Classpath有兩個屬性path和location,path指定jar包,location指定包含jar包的路徑。可以通過fileset和dirset簡化配置。
<classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
<dirset dir="${build.dir}">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</dirset>
<filelist refid="third-party_jars"/>
</classpath>
4.Ant流程控制 if elseif else
使用循環,判斷等控制時需添加ant-contrib包。
taskdef定義第三方的任務,主要包含ant的處理流程邏輯
if elseif else格式如下
<property name="hello" value="false"/>
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="D:\Program Files\apache-ant-1.8.4\lib\ant-contrib-1.0b3.jar" />
<target name="run" depends="compile">
<java classname="HelloWorld">
<classpath path="${classdir}"/>
</java>
<if>
<equals arg1="${hello}" arg2="true"/>
<then>
<echo>${hello} is true</echo>
</then>
<elseif>
<equals arg1="${hello}" arg2="false"/>
<then>
<echo>${hello} is false</echo>
</then>
</elseif>
<else>
<echo>${hello}</echo>
</else>
</if>
</target>
5.常用task
使用classpath
<target>
<javac>
<classpath refid="project.class.path"/>
</javac>
</target>
設定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>
輸出資訊
<echo message="XXX"/>
<echo>XXX</echo>
引入一個XML檔案
<import file="../common-targets.xml"/>
拷貝檔案
<copy file="myfile.txt" tofile="mycopy.txt"/>
<copy file="myfile.txt" todir="../otherdir"/>
<copy todir="..//newdir">
<fileset dir="src_dir"/>
</copy>
<copy todir="../destdir">
<fileset dir="src_dir">
<exclude name="**/*.java"/>
</fileset>
</copy>
<copy todir="../destdir">
<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="Foo Bar"/>
</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"/>
<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"/>
剪切檔案
<move todir="some/new/dir">
<fileset dir="my/src/dir">
<include name="**/*.jar"/>
<exclude name="**/ant.jar"/>
</fileset>
</move>
重命名
<rename src="foo.jar" dest="ant-${version}.jar"/>
建立臨時檔案
<!--在目錄build下,建立檔案名為temp.file,字尾名為xml的檔案-->
<tempfile property="temp.file" destDir="build" suffix=".xml"/>
Touch使用
<!--如果檔案不存在,建立檔案,如果存在,更改最後通路時間為目前系統時間-->
<touch file="myfile"/>
<!--如果檔案不存在,建立檔案,更改最後通路時間-->
<touch file="myfile" datetime="06/28/2000 2:02 pm"/>
<!--更改目錄下所有檔案的最後通路時間-->
<touch datetime="09/10/1974 4:30 pm">
<fileset dir="src_dir"/>
</touch>
Condition的使用 <and> <or> <not>等tag
peoperty: The name of the property to set
value: The value to set the property to.
else: The value to set the property to if the codition evaluates to false.
<condition property="isMacOsButNotMacOsX">
<and>
<os family="mac">
<not>
<os family="unix">
</not>
</and>
</condition>
替換
<replace
file="configure.sh"
value="defaultvalue"
propertyFile="src/name.properties">
<replacefilter
token="@token1@"/>
<replacefilter
token="@token2@"
value="value2"/>
<replacefilter
token="@token3@"
property="property.key"/>
<replacefilter>
<replacetoken>@token4@</replacetoken>
<replacevalue>value4</replacevalue>
</replacefilter>
</replace>
調用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>
設定property
<!--設定屬性name-value-->
<property name="foo.dist" value="dist"/>
<!--讀取屬性檔案中的屬性配置-->
<property file="foo.properties"/>
<!--讀取網絡中的property-set-->
<property url="http://www.mysite/props/foo.properties"/>
<!--讀取檔案中的屬性配置-->
<property resource="foo.properties"/>
<!--讀取環境變量-->
<property environment="env"/>
顯示錯誤資訊
Fail task 退出目前建構,抛出BuildException,列印錯誤資訊。
message:A message giving further information on why the build exited
if:Only fail if a property of the given name exists in the current project
unless:Only fail if a property of the given name doesn't exist in the current project
status:Exit using the specified status code; assuming the generated Exception is not caught, the JVM will exit with this status.Since Apache Ant 1.6.2
<fail>Something wrong here.</fail>
<fail message="${屬性}"/>
<!--如果這個屬性不存在,顯示錯誤-->
<fail unless="failCondition" message="unless Condition"/>
<!--如果這個屬性存在,顯示錯誤-->
<fail if="failCondition" message="if Condition"/>
<!--如果符合條件,顯示錯誤-->
<fial message="tag condition">
<condition>
<not>
<isset property="failCondition"/>
</not>
</condition>
</fail>
建立目錄
<mkdir dir="${dist}/lib"/>
打jar包
<jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/>
<jar destfile="${build}/lib/app.jar" basedir="${build}/classes" includes="mypackage/test/**" excludes="**/Test.class"/>
打ear包
<ear destfile="build/myapp.ear" appxml="src/metadata/application.xml">
<fileset dir="build" includes="*.jar,*war"/>
</ear>
執行程式
<target name="help">
<exec executable="cmd">
<arg value="/c">
<arg value="ant.bat"/>
<arg value="-p"/>
</exec>
</target>
運作jar包
<java classname="test.Main" dir="${exec.dir}" jar="${exec.dir}/dist/test.jar" fork="true" failonerror="true" maxmemory="128m">
<arg value="-h"/>
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="/Users/antoine/dev/asf/ant-core/bootstrap/lib/ant-launcher.jar"/>
</classpath>
</java>
編譯程式
<javac srcdir="${src}" destdit="${build}" classpath="xyz.jar" debug="on" source="1.4"/>
Length使用
<!--把字元串foo的長度儲存到屬性length.foo中-->
<length string="foo" property="length.foo"/>
<!--把檔案bar的長度儲存到屬性length.bar-->
<length file="bar" property="length.bar"/>
輸入input
輸入值儲存在db.user中
<input message="Please enter db-username:" addproperty="db.user" defaultvalue="Scott-Tiger"/>
壓縮、解壓縮
<!--解壓縮zip檔案-->
<unzip src="apache-ant-bin.zip" dest="${tools.home}">
<patternset>
<include name="apache-ant/lib/ant.jar"/>
</patternset>
<mapper type="flatten"/>
</unzip>
<!--壓縮zip檔案-->
<zip destfile="${dist}/manual.zip" basedir="htdoc/manual" includes="api/**/*.html" excludes="**/todo.html"/>
<!--打tar包-->
<tar destfile="/Users/antoine/dev/asf/ant-core/docs.tar">
<tarfileset dir="${dir.src}/doc" fullpath="/usr/doc/ant/README" preserveLeadingSlashes="true">
<include name="readme.txt"/>
<tarfileset>
<tarfileset dir="${dir.src}/docs" prefix="/usr/doc/ant" preserveLeadingSlashes="true">
<include name="*.html"/>
</tarfileset>
</tar>
<!--解壓tar包-->
<untar src="tools.tar" dest="${tools.home}"/>
打war包
<war destfile="myapp.war" webxml="src/metadata/myapp.xml">
<fileset dir="src/html/myapp"/>
<fileset dir="src/jsp/myapp"/>
<lib dir="thirdparty/libs">
<exclude name="jdbc1.jar">
</lib>
<classes dir="build/main"/>
<zipfileset dir="src/graphics/images/gifs" prefix="images"/>
</war>
如果本文對您有幫助,點一下右下角的“推薦”