一談到英語單詞Ant,人們很自然的想到螞蟻。而一談到另一個單詞Make,人們也會很自然想到構建工具。有誰會將這兩個詞關聯起來呢。那麼Ant究竟有什麼神奇之處呢。本文會為您揭曉答案。
什麼是Ant
Apache Ant是一個基於Java的構建(Build)工具。理論上講,類似Unix/Linux C程式員經常使用的Make工具。與Make相比,Ant完全由Java實現,具有跨平台的好處。
Ant的命名來源
至於Ant的稱呼,頗有點意思。據Ant原作者James Duncan Davidson本人介紹,Ant是“Another Neat Tool”的縮寫,意思是“另一個簡潔的工具”,意思是比Make更簡潔,適用。不過,人們更願意接受Ant即“螞蟻”這樣的理解。眾所周知,螞蟻是動物世界赫赫有名的建築師(ants do an extremely good job at building things);螞蟻體格雖小,但力氣超強(ants are very small and can carry a weight dozens of times their own)。
Ant的曆史
說起Ant,就不得不說另一個Apache開源項目Tomcat。Tomcat作為輕量級Web容器,早已聲名鵲起。最初,Ant其實是Tomcat的一部分,Ant的唯一目的就是build Tomcat。Ant原作者James Duncan Davidson也是Tomcat的創始人。
不久,很多Java開源項目意識到Ant的簡潔適用,更重要的是彌補Makefiles的不足。自從Jakarta以及Apache項目開始採用Ant以來, 作為構建工具,Ant就像病毒一樣,傳播到各種各樣的項目。
2000年1月,Ant脫離了Tomcat,成為獨立的Apache開源項目,由獨立的CVS模組維護,正式更名為Apache Ant。2000年7月,Apache Ant的第一個版本1.1正式亮相。截至筆者發稿時,Apache Ant的最新版本為1.8.2,發布日期為2010年12月27日。點擊http://ant.apache.org/bindownload.cgi下載最新版本。
Ant的安裝
在簡單介紹Ant的相關背景之後,我們以Windows平台為例,介紹如何安裝Ant。
為順利安裝Ant,請確保Java版本在1.4以上,推薦1.5。為確保Ant功能全部可用,請使用JDK,不推薦使用JRE。 第一種方式是選擇Windows installer for Apache Ant自動安裝,預設Ant安裝目錄為C:\Program Files\WinAnt 。並自動建立環境變數ANT_HOME與PATH,指向Ant根目錄。這種方式的特點是簡單、迅速。 第二種方式是手工安裝。具體方法如下:
1. 下載。如前述所,從ANT Binary Page(http://ant.apache.org/bindownload.cgi)下載Ant二進位安裝包a.zip。解壓後目錄如下:
bin – 公用的二進位檔案,以及運行指令碼
build – 臨時建立的檔案,如.class檔案
dist – 目標輸出檔案,如.jar檔案
docs – 文檔
lib – 需要匯出的jar包
src – 源檔案
2. 指定ANT_HOME變數。開啟控制台 -> 系統 –> 進階 –> 環境變數。建立使用者變數ANT_HOME,值為zip包解壓路徑。例如:
變數名:”ANT_HOME”
變數值:"C:\Program Files\Apache Software Foundation\apache-ant-1.8.1"
3. 將ANT_HOME加入PATH變數。
變數名:" PATH"
變數值:" ;%ANT_HOME%\bin"
4. 建立使用者變數JAVA_HOME,值為Java安裝目錄。例如:
變數名:”JAVA_HOME”
變數值:"C:\Program Files\Java\jdk1.6.0_21"
建立使用者變數JAVA_HOME,值為Java安裝目錄。JAVA_HOME = C:\Program Files\java\jdk1.6.0_02
5. 將JAVA_HOME加入PATH變數。
變數名:" PATH"
變數值:" ;%JAVA_HOME%\bin"
相比於前一種,第二種方式更加靈活。
無論哪種方式,可以使用下列辦法確保安裝成功,
• 使用javac –version檢查Java環境是否正確。傳回值應為:javac 1.6.0_21
• 使用ant –version檢查Ant環境是否正確。傳回值應為:Apache Ant version 1.8.1 compiled on April 30 2010。
如圖所示:
如果遇到安裝錯誤,請參見Apache Ant官方網站:http://ant.apache.org/problems.html。
第一個Ant樣本
假設我們建立一個Java工程HelloWorld,將源檔案.java存放在src目錄,編譯後的位元組碼.class存放在bin目錄,對應的jar包存放在exe目錄,結構如下圖:
HelloWorld.java清單如下:
public class HelloWorld {
public static void main( String [] args) {
System.out.println( " Hello World " );
}
}
我們分別採用命令列與Ant兩種不同的build方式。
1. 命令列
首先,建立src目錄: md src
其次,建立bin目錄,編譯並運行: md bin
javac - sourcepath src - d bin \ src \ HelloWorld.java
java - cp bin HelloWorld
再次,建立exe目錄,建立jar包,包含建立manifest檔案,exe目錄,jar打包。一個命令就可以搞定: echo Main - Class: HelloWorld > MonManifest md exe jar cfm exe \ HelloWorld.jar MonManifest - C bin .
最後,運行工程: java - jar exe \ HelloWorld.jar
2. Ant
Ant的構建指令檔build file是使用XML語言編寫,下文我們簡稱為build.xml。build.xml包含一個標準的根節點Project,表示一個工程。每個build檔案只允許定義一個Project元素。Project定義至少1個或多個Target,表示不同的模組。而Target又是一些列Task的集合,而每一個Task是一段可執行檔代碼。三者的關係如圖表示。更多細節,請參見Apache Ant官方網站:http://ant.apache.org。
我們使用Ant來build工程HelloWorld。build.xml包含4個target:clean,compile,jar,run。
clean
clean清除所有的編譯檔案以及相關目錄,這裡為目錄bin以及exe。 < target name = ” clean ” >
< delete dir = ” bin ” / >
< delete dir = ” exe ” / >
< / target >
compile
compile建立目錄bin,編譯src目錄源檔案,產生的.class檔案放在bin目錄。 < target name = ” compile ” >
< mkdir dir = ” bin ” / >
< javac srcdir = ” src ” destdir = ” bin ” / >
< / target >
jar
jar建立目錄exe,打包jar。使用manifest元素可輕鬆建立manifest檔案。 < target name = ” jar ” >
< mkdir dir = ” exe ” / >
< jar destfile = ” exe / HelloWorld.jar ” basedir = ” bin ” >
< manifest >
< attribute name = ” Main - Class ” value = ” HelloWorld ” / >
< / manifest >
< / jar >
< / target >
run
run 運行jar。 < target name = ” run ” >
< java jar = ” exe / HelloWorld.jar ” fork = ” true ” / >
< / target >
需要指出的是,以上4個target的執行順序上有依賴關係的。例如jar依賴於compile,run依賴於jar。Ant提供了屬性depends來描述target之間的依賴關係。舉個例子,假設執行D,由於D依賴於C,C依賴於B,B依賴於A,因此,從順序上,先執行A,其次B,然後C,最後D。每個Target最多隻能被執行一遍。 < target name = ” A ” / >
< target name = ” B ” depends = “ A “ / >
< target name = ” C ” depends = “ B “ / >
< target name = ” D ” depends = “ C,B,A “ / >
對於我們的工程HelloWorld。可以運行下列Ant命令。 ant clean
ant compile
ant jar
ant run
當然,可以簡單地運行 ant run
build.xml清單如下: < project default = ” run ” >
< property name = ” src.dir ” value = ” src ” / >
< property name = ” bin.dir ” value = ” bin ” / >
< property name = ” jar.dir ” value = ” exe ” / >
< property name = ” main - class ” value = ” HelloWorld ” / >
< target name = ” clean ” >
< delete dir = ” ${bin.dir} ” / >
< delete dir = ” ${jar.dir} ” / >
< echo message = ” nettoyage termine ” / >
< / target >
< target name = ” compile ” depends = ” clean ” >
< mkdir dir = ” ${bin.dir} ” / >
< javac srcdir = ” ${src.dir} ” destdir = ” ${bin.dir} ” / >
< echo message = ” compilation terminee ” / >
< / target >
< target name = ” jar ” depends = ” compile ” >
< mkdir dir = ” ${jar.dir} ” / >
< jar destfile = ” ${jar.dir} / sdf.jar ” basedir = ” ${bin.dir} ” >
< manifest >
< attribute name = ” Main - Class ” value = ” ${main - class} ” / >
< / manifest >
< / jar >
< echo message = ” Creation du fichier Jar terminee ” / >
< / target >
< target name = ” run ” depends = ” jar ” >
< java jar = ” ${jar.dir} / sdf.jar ” fork = ” true ” / >
< / target >
< / project >
Eclipse提供Ant視圖,可以很方便查看與編輯Ant指令碼,如圖:
Ant API
Ant的強大之處在於,不僅可以調用Ant指令碼進行各種檔案部署、管理工作,也可以調用Ant豐富的API,甚至擴充Ant API編程。舉幾個例子:
1. 建立目錄: Project prj = new Project();
Mkdir mkdir = new Mkdir();
mkdir.setProject(prj);
mkdir.setDir( new File( " src " ));
mkdir.execute();
2. 將class檔案打成jar包 Project prj = new Project();
Jar jar = new Jar();
jar.setProject(prj);
jar.setDestFile( new File( " HelloWorld.jar " ));
FileSet fileSet = new FileSet();
fileSet.setProject(prj);
fileSet.setDir( new File( " bin " ));
fileSet.setIncludes( " **/*.class " );
jar.addFileset(fileSet);
jar.execute();
建立自己的Task
Apache Ant允許使用者自訂Task,步驟如下:
1. 建立一個類,繼承org.apache.tools.ant.Task
2. 對於每一個Attribute,需要實現標準的Java bean規範的set方法。
3. 如果建立的Task需要其它其它的子Task,則需要實現org.apache.tools.ant.TaskContainer介面。
4. 如果擴充的Task需要支援Text,需要實現方法public void addText(String)。
5. 對於每個嵌套的元素,實現create, add或者addConfigured方法。
6. 實現public void execute()方法。
7. 在build.xml中使用引用自訂Task。
舉個例子,我們寫一個自訂的Task,目的是在Java控制台列印一條訊息。該Task只有一個屬性,稱為message。
原始碼MyTask.java import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class MyTask extends Task {
private String msg;
// The method executing the task
public void execute () throws BuildException {
System.out.println(msg);
}
// The setter for the " message " attribute
public void setMessage( String msg) {
this.msg = msg;
}
}
對應的build.xml < ?xml version = " 1.0 " ? >