Ant指南
1. Ant是什么?
2. 安裝Ant
3. 運行Ant
4. 編寫build.xml
5. 內(nèi)置task(internet)
6. EAR task(internet)
7. WAR task(internet)
8. JUnit task(internet)
1. Ant是什么?
2. 安裝Ant
3. 運行Ant
4. 編寫build.xml
5. 內(nèi)置task(internet)
6. EAR task(internet)
7. WAR task(internet)
8. JUnit task(internet)
1. Ant是什么?
Ant是一種基于Java的build工具。理論上來說,它有些類似于(Unix)C中的make ,但沒有make的缺陷。2. 安裝Ant
既然我們已經(jīng)有了make, gnumake, nmake, jam以及其他的build工具為什么還要要一種新的build工具呢?因為Ant的原作者在多種(硬件)平臺上開發(fā)軟件時,無法忍受這些工具的限制和不便。類似于make的工具本質(zhì)上是基于shell(語言)的:他們計算依賴關(guān)系,然后執(zhí)行命令(這些命令與你在命令行敲的命令沒太大區(qū)別)。這就意味著你可以很容易地通過使用OS特有的或編寫新的(命令)程序擴(kuò)展該工具;然而,這也意味著你將自己限制在了特定的OS,或特定的OS類型上,如Unix。
Makefile也很可惡。任何使用過他們的人都碰到過可惡的tab問題。Ant的原作者經(jīng)常這樣問自己:“是否我的命令不執(zhí)行只是因為在我的tab前有一個空格?!!”。類似于jam的工具很好地處理了這類問題,但是(用戶)必須記住和使用一種新的格式。
Ant就不同了。與基于shell命令的擴(kuò)展模式不同,Ant用Java的類來擴(kuò)展。(用戶)不必編寫shell命令,配置文件是基于XML的,通過調(diào)用target樹,就可執(zhí)行各種task。每個task由實現(xiàn)了一個實現(xiàn)了特定Task接口的對象來運行。(如果你對Ant一點概念都沒有的話,可能看不懂這一節(jié),沒有關(guān)系,后面會對target,task做詳細(xì)的介紹。你如果沒有太多的時間甚至可以略過這一節(jié),然后再回來瀏覽一下這里的介紹,那時你就會看懂了。同樣,如果你對make之類的工具不熟悉也沒關(guān)系,下面的介紹根本不會用到make中的概念。)
必須承認(rèn),這樣做,在構(gòu)造shell命令時會失去一些特有的表達(dá)能力。如`find . -name foo -exec rm {}`,但卻給了你跨平臺的能力-你可以在任何地方工作。如果你真的需要執(zhí)行一些shell命令,Ant有一個<exec> task,這個task允許執(zhí)行特定OS上的命令。
返回
由于Ant是一個Open Source的軟件,所以有兩種安裝Ant的方式,一種是用已編譯好的binary 文件安裝Ant,另一種是用源代碼自己build Ant。3. 運行Ant
binary 形式的Ant可以從http://jakarta.apache.org/builds/ant/release/v1.4.1/bin下載。如果你希望你能自己編譯Ant,則可從 http://jakarta.apache.org/builds/ant/release/v1.4.1/src。注意所列出的連接都是最新發(fā)行版的Ant。如果你讀到此文時,發(fā)現(xiàn)已經(jīng)有了更新的版本,那么請用新版本。如果你是一個瘋狂的技術(shù)追求者,你也可以從Ant CVS repository下載最新版本的Ant。
系統(tǒng)需求
要想自己build Ant。你需要一個JAXP兼容的XML解析器(parser)放在你的CLASSPATH系統(tǒng)變量中。
binary 形式的Ant包括最新版的Apache Crimson XML解析器。你可以從http://java.sun.com/xml/ 得到更多的關(guān)于JAXP的信息。如果你希望使用其他的JAXP兼容的解析器。你要從Ant的lib目錄中刪掉jaxp.jar以及crimson.jar。然后你可將你心愛的解析器的jar文件放到Ant的lib目錄中或放在你的CLASSPATH系統(tǒng)變量中。
對于當(dāng)前版本的Ant,需要你的系統(tǒng)中有JDK,1.1版或更高。未來的Ant版本會要求使用JDK 1.2或更高版本。
安裝Ant
binary 版的Ant包括三個目錄:bin, docs 和lib。只有bin和lib目錄是運行Ant所需的。要想安裝Ant,選擇一個目錄并將發(fā)行版的文件拷貝到該目錄下。這個目錄被稱作ANT_HOME。
在你運行Ant之前需要做一些配置工作。注意:不要將Ant的ant.jar文件放到JDK/JRE的lib/ext目錄下。Ant是個應(yīng)用程序,而lib/ext目錄是為JDK擴(kuò)展使用的(如JCE,JSSE擴(kuò)展)。而且通過擴(kuò)展裝入的類會有安全方面的限制。
- 將bin目錄加入PATH環(huán)境變量。
- 設(shè)定ANT_HOME環(huán)境變量,指向你安裝Ant的目錄。在一些OS上,Ant的腳本可以猜測ANT_HOME(Unix和Windos NT/2000)-但最好不要依賴這一特性。
- 可選地,設(shè)定JAVA_HOME環(huán)境變量(參考下面的高級小節(jié)),該變量應(yīng)該指向你安裝JDK的目錄。
可選Task
Ant支持一些可選task。一個可選task一般需要額外的庫才能工作。可選task與Ant的內(nèi)置task分開,單獨打包。這個可選包可以從你下載Ant的同一個地方下載。目前包含可選task的jar文件名叫jakarta-ant-1.4.1-optional.jar。這個jar文件應(yīng)該放到Ant安裝目錄的lib目錄下。
每個可選task所需的外部庫可參看依賴庫小節(jié)。這些外部庫可以放到Ant的lib目錄下,這樣Ant就能自動裝入,或者將其放入環(huán)境變量中。
Windows
假定Ant安裝在c:\ant\目錄下。下面是設(shè)定環(huán)境的命令:set ANT_HOME=c:\antUnix (bash)
set JAVA_HOME=c:\jdk1.2.2
set PATH=%PATH%;%ANT_HOME%\bin
假定Ant安裝在/usr/local/ant目錄下。下面是設(shè)定環(huán)境的命令:export ANT_HOME=/usr/local/ant高級
export JAVA_HOME=/usr/local/jdk-1.2.2
export PATH=${PATH}:${ANT_HOME}/bin
要想運行Ant必須使用很多的變量。你至少參考需要下面的內(nèi)容:Building Ant
- Ant的CLASSPATH必須包含ant.jar以及你所選的JAXP兼容的XML解析器的jar文件。
- 當(dāng)你需要JDK的功能(如javac或rmic task)時,對于JDK 1.1,JDK的classes.zip文件必須放入CLASSPATH中;對于JDK 1.2或JDK 1.3,則必須加入tools.jar。如果設(shè)定了正確的JAVA_HOME環(huán)境變量,Ant所帶的腳本,在bin目錄下,會自動加入所需的JDK類。
- 當(dāng)你執(zhí)行特定平臺的程序(如exec task或cvs task)時,必須設(shè)定ant.home屬性指向Ant的安裝目錄。同樣,Ant所帶的腳本利用ANT_HOME環(huán)境變量自動設(shè)置該屬性。
要想從源代碼build Ant,你要先安裝Ant源代碼發(fā)行版或從CVS中checkout jakarta-ant模塊。
安裝好源代碼后,進(jìn)入安裝目錄。
設(shè)定JAVA_HOME環(huán)境變量指向JDK的安裝目錄。要想知道怎么做請參看安裝Ant小節(jié)。
確保你已下載了任何輔助jar文件,以便build你所感興趣的task。這些jar文件可以放在CLASSPATH中,也可以放在lib/optional目錄下。參看依賴庫小節(jié)可知不同的task需要那些jar文件。注意這些jar文件只是用作build Ant之用。要想運行Ant,你還要像安裝Ant小節(jié)中所做的那樣設(shè)定這些jar文件。
現(xiàn)在你可以build Ant了:build -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Windows)這樣就可你指定的目錄中創(chuàng)建一個binary版本。
build.sh -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Unix)
上面的命令執(zhí)行下面的動作:大多數(shù)情況下,你不必直接bootstrap Ant,因為build腳本為你完成這一切。運行bootstrap.bat (Windows) 或 bootstrap.sh (UNIX) 可以build一個新的bootstrap版Ant。
- 如果有必要可以bootstrap Ant的代碼。bootstrap 包括手工編輯一些Ant代碼以便運行Ant。bootstrap 用于下面的build步驟。
- 向build腳本傳遞參數(shù)以調(diào)用bootstrap Ant。參數(shù)定義了Ant的屬性值并指定了Ant自己的build.xml文件的"dist" target。
如果你希望將Ant安裝到ANT_HOME目錄下,你可以使用:build install (Windows)如果你希望跳過冗長的Javadoc步驟,可以用:
build.sh install (Unix)build install-lite (Windows)這樣就只會安裝bin和lib目錄。
build.sh install-lite (Unix)
注意install和install-lite都會覆蓋ANT_HOME中的當(dāng)前Ant版本。
依賴庫
如果你需要執(zhí)行特定的task,你需要將對應(yīng)的庫放入CLASSPATH或放到Ant安裝目錄的lib目錄下。注意使用mapper時只需要一個regexp庫。同時,你也要安裝Ant的可選jar包,它包含了task的定義。參考上面的安裝Ant小節(jié)。
Jar Name Needed For Available At An XSL transformer like Xalan or XSL:P style task http://xml.apache.org/xalan-j/index.html or http://www.clc-marketing.com/xslp/ jakarta-regexp-1.2.jar regexp type with mappers jakarta.apache.org/regexp/ jakarta-oro-2.0.1.jar regexp type with mappers and the perforce tasks jakarta.apache.org/oro/ junit.jar junit tasks www.junit.org stylebook.jar stylebook task CVS repository of xml.apache.org testlet.jar test task java.apache.org/framework antlr.jar antlr task www.antlr.org bsf.jar script task oss.software.ibm.com/developerworks/projects/bsf netrexx.jar netrexx task www2.hursley.ibm.com/netrexx rhino.jar javascript with script task www.mozilla.org jpython.jar python with script task www.jpython.org netcomponents.jar ftp and telnet tasks www.savarese.org/oro/downloads
返回
運行Ant非常簡單,當(dāng)你正確地安裝Ant后,只要輸入ant就可以了。4. 編寫build.xml
沒有指定任何參數(shù)時,Ant會在當(dāng)前目錄下查詢build.xml文件。如果找到了就用該文件作為buildfile。如果你用 -find 選項。Ant就會在上級目錄中尋找buildfile,直至到達(dá)文件系統(tǒng)的根。要想讓Ant使用其他的buildfile,可以用參數(shù) -buildfile file,這里file指定了你想使用的buildfile。
你也可以設(shè)定一些屬性,以覆蓋buildfile中指定的屬性值(參看property task)。可以用 -Dproperty=value 選項,這里property是指屬性的名稱,而value則是指屬性的值。也可以用這種辦法來指定一些環(huán)境變量的值。你也可以用property task來存取環(huán)境變量。只要將 -DMYVAR=%MYVAR% (Windows) 或 -DMYVAR=$MYVAR (Unix) 傳遞給Ant -你就可以在你的buildfile中用${MYVAR}來存取這些環(huán)境變量。
還有兩個選項 -quite,告訴Ant運行時只輸出少量的必要信息。而 -verbose,告訴Ant運行時要輸出更多的信息。
可以指定執(zhí)行一個或多個target。當(dāng)省略target時,Ant使用標(biāo)簽<project>的default屬性所指定的target。
如果有的話,-projecthelp 選項輸出項目的描述信息和項目target的列表。先列出那些有描述的,然后是沒有描述的target。
命令行選項總結(jié):ant [options] [target [target2 [target3] ...]]例子
Options:
-help print this message
-projecthelp print project help information
-version print the version information and exit
-quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
-emacs produce logging information without adornments
-logfile file use given file for log output
-logger classname the class that is to perform logging
-listener classname add an instance of class as a project listener
-buildfile file use specified buildfile
-find file search for buildfile towards the root of the filesystem and use the first one found
-Dproperty=value set property to valueant使用當(dāng)前目錄下的build.xml運行Ant,執(zhí)行缺省的target。ant -buildfile test.xml使用當(dāng)前目錄下的test.xml運行Ant,執(zhí)行缺省的target。ant -buildfile test.xml dist使用當(dāng)前目錄下的test.xml運行Ant,執(zhí)行一個叫做dist的target。ant -buildfile test.xml -Dbuild=build/classes dist使用當(dāng)前目錄下的test.xml運行Ant,執(zhí)行一個叫做dist的target,并設(shè)定build屬性的值為build/classes。
文件
在Unix上,Ant的執(zhí)行腳本在做任何事之前都會source(讀并計算值)~/.antrc 文件;在Windows上,Ant的批處理文件會在開始時調(diào)用%HOME%\antrc_pre.bat,在結(jié)束時調(diào)用%HOME%\antrc_post.bat。你可以用這些文件配置或取消一些只有在運行Ant時才需要的環(huán)境變量。看下面的例子。
環(huán)境變量
包裹腳本(wrapper scripts)使用下面的環(huán)境變量(如果有的話):手工運行Ant
- JAVACMD Java可執(zhí)行文件的絕對路徑。用這個值可以指定一個不同于JAVA_HOME/bin/java(.exe)的JVM。
- ANT_OPTS 傳遞給JVM的命令行變量-例如,你可以定義屬性或設(shè)定Java堆的最大值
如果你自己動手安裝(DIY)Ant,你可以用下面的命令啟動Ant:java -Dant.home=c:\ant org.apache.tools.ant.Main [options] [target]這個命令與前面的ant命令一樣。選項和target也和用ant命令時一樣。這個例子假定你的CLASSPATH包含:返回
- ant.jar
- jars/classes for your XML parser
- the JDK's required jar/zip files
Ant的buildfile是用XML寫的。每個buildfile含有一個project。
buildfile中每個task元素可以有一個id屬性,可以用這個id值引用指定的任務(wù)。這個值必須是唯一的。(詳情請參考下面的Task小節(jié))
Projects
project有下面的屬性:項目的描述以一個頂級的<description>元素的形式出現(xiàn)(參看description小節(jié))。
Attribute Description Required name 項目名稱. No default 當(dāng)沒有指定target時使用的缺省target Yes basedir 用于計算所有其他路徑的基路徑。該屬性可以被basedir property覆蓋。當(dāng)覆蓋時,該屬性被忽略。如果屬性和basedir property都沒有設(shè)定,就使用buildfile文件的父目錄。 No
一個項目可以定義一個或多個target。一個target是一系列你想要執(zhí)行的。執(zhí)行Ant時,你可以選擇執(zhí)行那個target。當(dāng)沒有給定target時,使用project的default屬性所確定的target。
Targets
一個target可以依賴于其他的target。例如,你可能會有一個target用于編譯程序,一個target用于生成可執(zhí)行文件。你在生成可執(zhí)行文件之前必須先編譯通過,所以生成可執(zhí)行文件的target依賴于編譯target。Ant會處理這種依賴關(guān)系。
然而,應(yīng)當(dāng)注意到,Ant的depends屬性只指定了target應(yīng)該被執(zhí)行的順序-如果被依賴的target無法運行,這種depends對于指定了依賴關(guān)系的target就沒有影響。
Ant會依照depends屬性中target出現(xiàn)的順序(從左到右)依次執(zhí)行每個target。然而,要記住的是只要某個target依賴于一個target,后者就會被先執(zhí)行。<target name="A"/>假定我們要執(zhí)行target D。從它的依賴屬性來看,你可能認(rèn)為先執(zhí)行C,然后B,最后A被執(zhí)行。錯了,C依賴于B,B依賴于A,所以先執(zhí)行A,然后B,然后C,最后D被執(zhí)行。
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
一個target只能被執(zhí)行一次,即時有多個target依賴于它(看上面的例子)。
如果(或如果不)某些屬性被設(shè)定,才執(zhí)行某個target。這樣,允許根據(jù)系統(tǒng)的狀態(tài)(java version, OS, 命令行屬性定義等等)來更好地控制build的過程。要想讓一個target這樣做,你就應(yīng)該在target元素中,加入if(或unless)屬性,帶上target因該有所判斷的屬性。例如:<target name="build-module-A" if="module-A-present"/>如果沒有if或unless屬性,target總會被執(zhí)行。
<target name="build-own-fake-module-A" unless="module-A-present"/>
可選的description屬性可用來提供關(guān)于target的一行描述,這些描述可由-projecthelp命令行選項輸出。
將你的tstamp task在一個所謂的初始化target是很好的做法,其他的target依賴這個初始化target。要確保初始化target是出現(xiàn)在其他target依賴表中的第一個target。在本手冊中大多數(shù)的初始化target的名字是"init"。
target有下面的屬性:
Attribute Description Required name target的名字 Yes depends 用逗號分隔的target的名字列表,也就是依賴表。 No if 執(zhí)行target所需要設(shè)定的屬性名。 No unless 執(zhí)行target需要清除設(shè)定的屬性名。 No description 關(guān)于target功能的簡短描述。 No
Tasks
一個task是一段可執(zhí)行的代碼。
一個task可以有多個屬性(如果你愿意的話,可以將其稱之為變量)。屬性只可能包含對property的引用。這些引用會在task執(zhí)行前被解析。
下面是Task的一般構(gòu)造形式:<name attribute1="value1" attribute2="value2" ... />這里name是task的名字,attributeN是屬性名,valueN是屬性值。
有一套內(nèi)置的(built-in)task,以及一些可選task,但你也可以編寫自己的task。
所有的task都有一個task名字屬性。Ant用屬性值來產(chǎn)生日志信息。
可以給task賦一個id屬性:<taskname id="taskID" ... />這里taskname是task的名字,而taskID是這個task的唯一標(biāo)識符。通過這個標(biāo)識符,你可以在腳本中引用相應(yīng)的task。例如,在腳本中你可以這樣:<script ... >設(shè)定某個task實例的foo屬性。在另一個task中(用java編寫),你可以利用下面的語句存取相應(yīng)的實例。
task1.setFoo("bar");
</script>project.getReference("task1").注意1:如果task1還沒有運行,就不會被生效(例如:不設(shè)定屬性),如果你在隨后配置它,你所作的一切都會被覆蓋。
注意2:未來的Ant版本可能不會兼容這里所提的屬性,因為很有可能根本沒有task實例,只有proxies。
Properties
一個project可以有很多的properties。可以在buildfile中用property task來設(shè)定,或在Ant之外設(shè)定。一個property有一個名字和一個值。property可用于task的屬性值。這是通過將屬性名放在"${"和"}"之間并放在屬性值的位置來實現(xiàn)的。例如如果有一個property builddir的值是"build",這個property就可用于屬性值:${builddir}/classes。這個值就可被解析為build/classes。
內(nèi)置屬性
如果你使用了<property> task 定義了所有的系統(tǒng)屬性,Ant允許你使用這些屬性。例如,${os.name}對應(yīng)操作系統(tǒng)的名字。
要想得到系統(tǒng)屬性的列表可參考the Javadoc of System.getProperties。
除了Java的系統(tǒng)屬性,Ant還定義了一些自己的內(nèi)置屬性:basedir project基目錄的絕對路徑 (與<project>的basedir屬性一樣)。 ant.file buildfile的絕對路徑。 ant.version Ant的版本。 ant.project.name 當(dāng)前執(zhí)行的project的名字;由<project>的name屬性設(shè)定. ant.java.version Ant檢測到的JVM的版本; 目前的值有"1.1", "1.2", "1.3" and "1.4".例子<project name="MyProject" default="dist" basedir="."> <!-- set global properties for this build --> <property name="src" value="."/> <property name="build" value="build"/> <property name="dist" value="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"> <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <!-- 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"> <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>Token Filters
一個project可以有很多tokens,這些tokens在文件拷貝時會被自動擴(kuò)展,這要求在支持這一行為的task中選擇過濾拷貝功能。這一功能可用filter task在buildfile中設(shè)定。
既然這很可能是一個有危害的行為,文件中的tokens必須采取@token@的形式,這里token是filter task中設(shè)定的token名。這種token語法與其他build系統(tǒng)執(zhí)行類似filtering的語法相同,而且與大多數(shù)的編程和腳本語言以及文檔系統(tǒng)并不沖突,
注意:如果在一個文件中發(fā)現(xiàn)了一個@token@形式的token,但沒有filter與這個token關(guān)連,則不會發(fā)生任何事;因此,沒有轉(zhuǎn)義方法-但只要你為token選擇合適的名字,就不會產(chǎn)生問題。
警告:如果你在拷貝binary文件時打開filtering功能,你有可能破壞文件。這個功能只針對文本文件。
Path-like Structures
你可以用":"和";"作為分隔符,指定類似PATH和CLASSPATH的引用。Ant會把分隔符轉(zhuǎn)換為當(dāng)前系統(tǒng)所用的分隔符。
當(dāng)需要指定類似路徑的值時,可以使用嵌套元素。一般的形式是<classpath> <pathelement path="${classpath}"/> <pathelement location="lib/helper.jar"/> </classpath>location屬性指定了相對于project基目錄的一個文件和目錄,而path屬性接受逗號或分號分隔的一個位置列表。path屬性一般用作預(yù)定義的路徑--其他情況下,應(yīng)該用多個location屬性。
為簡潔起見,classpath標(biāo)簽支持自己的path和location屬性。所以:<classpath> <pathelement path="${classpath}"/> </classpath>可以被簡寫作:<classpath path="${classpath}"/>也可通過<fileset>元素指定路徑。構(gòu)成一個fileset的多個文件加入path-like structure的順序是未定的。<classpath> <pathelement path="${classpath}"/> <fileset dir="lib"> <include name="**/*.jar"/> </fileset> <pathelement location="classes"/> </classpath>上面的例子構(gòu)造了一個路徑值包括:${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>前面所提的關(guān)于<classpath>的簡潔寫法對于<path>也是有效的,如:<path id="tests.path"> <path refid="base.path"/> <pathelement location="testclasses"/> </path>可寫成:<path id="base.path" path="${classpath}"/>命令行變量
有些task可接受參數(shù),并將其傳遞給另一個進(jìn)程。為了能在變量中包含空格字符,可使用嵌套的arg元素。
Attribute Description Required value 一個命令行變量;可包含空格字符。 只能用一個 line 空格分隔的命令行變量列表。 file 作為命令行變量的文件名;會被文件的絕對名替代。 path 一個作為單個命令行變量的path-like的字符串;或作為分隔符,Ant會將其轉(zhuǎn)變?yōu)樘囟ㄆ脚_的分隔符。
例子<arg value="-l -a"/>是一個含有空格的單個的命令行變量。<arg line="-l -a"/>是兩個空格分隔的命令行變量。<arg path="/dir;/dir2:\dir3"/>是一個命令行變量,其值在DOS系統(tǒng)上為\dir;\dir2;\dir3;在Unix系統(tǒng)上為/dir:/dir2:/dir3 。
References
buildfile元素的id屬性可用來引用這些元素。如果你需要一遍遍的復(fù)制相同的XML代碼塊,這一屬性就很有用--如多次使用<classpath>結(jié)構(gòu)。
下面的例子:<project ... > <target ... > <rmic ...> <classpath> <pathelement location="lib/"/> <pathelement path="${java.class.path}/"/> <pathelement path="${additional.path}"/> </classpath> </rmic> </target> <target ... > <javac ...> <classpath> <pathelement location="lib/"/> <pathelement path="${java.class.path}/"/> <pathelement path="${additional.path}"/> </classpath> </javac> </target> </project>可以寫成如下形式:<project ... > <path id="project.class.path"> <pathelement location="lib/"/> <pathelement path="${java.class.path}/"/> <pathelement path="${additional.path}"/> </path> <target ... > <rmic ...> <classpath refid="project.class.path"/> </rmic> </target> <target ... > <javac ...> <classpath refid="project.class.path"/> </javac> </target> </project>所有使用PatternSets, FileSets 或 path-like structures嵌套元素的task也接受這種類型的引用。