近期碰到了其餘人在討論這個ant,已經不少人在使用,故對他進行收集資料進了解,以便方便去使用。同時,在學習struts+spring+hibernate,尤爲是Appfuse的過程當中大量涉及到ant的使用,所以我以爲有必要對ant作個比較深刻的學習。html
ANT 是著名 Java 開源組織 Apache 的一個項目,是一個基於 java 的 build 工具。它可使你經過 ant 腳本語言,自動你的項目拷貝到某個目錄,發佈項目,或者生成 一些代碼,執行 SQL 語言。總之它能夠幫助你完成項目開發中除了開發代碼之外的大部分輔 助性工做。java
當一個代碼項目大了之後,每次從新編譯,打包,測試等都會變得很是復 雜並且重複。JAVA 使用 ANT(一種流程腳本引擎),用於自動化調用程序完成項目的編譯, 打包,測試等工做。每一個 ANT 腳本(缺省叫 build.xml)中設置了一系列任務(target)。mysql
Ant基本使用指南 web
Ant基本使用指南spring
1 Ant是什麼?sql
Apache Ant 是一個基於 Java的生成工具。shell
生成工具在軟件開發中用來將源代碼和其餘輸入文件轉換爲可執行文件的形式(也有可能轉換爲可安裝的產品映像形式)。隨着應用程序的生成過程變得更加複雜,確保在每次生成期間都使用精確相同的生成步驟,同時實現儘量多的自動化,以便及時產生一致的生成版本apache
2下載、安裝Antapi
安裝Ant安全
下載.zip文件,解壓縮到c:\ant1.3(後面引用爲%ANT_HOME%)
2.1在你運行Ant以前須要作一些配置工做。
·將bin目錄加入PATH環境變量。
·設定ANT_HOME環境變量,指向你安裝Ant的目錄。在一些OS上,Ant的腳本能夠猜想ANT_HOME(Unix和Windos NT/2000)-但最好不要依賴這一特性。
·可選地,設定JAVA_HOME環境變量(參考下面的高級小節),該變量應該指向你安裝JDK的目錄。
注意:不要將Ant的ant.jar文件放到JDK/JRE的lib/ext目錄下。Ant是個應用程序,而lib/ext目錄是爲JDK擴展使用的(如JCE,JSSE擴展)。並且經過擴展裝入的類會有安全方面的限制。
2.2運行Ant
運行Ant很是簡單,當你正確地安裝Ant後,只要輸入ant就能夠了。
沒有指定任何參數時,Ant會在當前目錄下查詢build.xml文件。若是找到了就用該文件做爲buildfile。若是你用 -find 選項。Ant就會在上級目錄中尋找buildfile,直至到達文件系統的根。要想讓Ant使用其餘的buildfile,能夠用參數 -buildfile file,這裏file指定了你想使用的buildfile。
能夠指定執行一個或多個target。當省略target時,Ant使用標籤<project>的default屬性所指定的target。
命令行選項總結:
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 value
Ant 命令行參考
從命令行調用Ant 的語法以下所示:
ant [option [option...]] [target [target...]]
option := {-help
|-projecthelp
|-version
|-quiet
|-verbose
|-debug
|-emacs
|-logfile filename
|-logger classname
|-listener classname
|-buildfile filename
|-Dproperty=value
|-find filename}
語法元素說明以下:
-help
顯示描述Ant 命令及其選項的幫助信息。
-projecthelp
顯示包含在構建文件中的、全部用戶編寫的幫助文檔。即爲各個<target>
中description 屬性的文本,以及包含在<description>元素中的任何文
本。將有description 屬性的目標列爲主目標(「Main target」),沒有此屬
性的目標則列爲子目標(「Subtarget」)。
-version
要求Ant 顯示其版本信息,而後退出。
-quiet
抑制並不是由構建文件中的echo 任務所產生的大多數消息。
-verbose
顯示構建過程當中每一個操做的詳細消息。此選項與-debug 選項只能選其一。
-debug
顯示Ant 和任務開發人員已經標誌爲調試消息的消息。此選項與-verbose 只
能選其一。
-emacs
對日誌消息進行格式化,使它們可以很容易地由Emacs 的shell 模式(shellmode)
所解析;也就是說,打印任務事件,但並不縮排,在其以前也沒有
[taskname]。
-logfile filename
將日誌輸出重定向到指定文件。
-logger classname
指定一個類來處理Ant 的日誌記錄。所指定的類必須實現了org.apache.
tools.ant.BuildLogger 接口。
-listener classname
爲Ant 聲明一個監聽類,並增長到其監聽者列表中。在Ant與IDE或其餘Java
程序集成時,此選項很是有用。能夠閱讀第六章以瞭解有關監聽者的更多信
息。必須將所指定的監聽類編寫爲能夠處理Ant 的構建消息接發。
-buildfile filename
指定Ant 須要處理的構建文件。默認的構建文件爲build.xml。
-Dproperty=value
在命令行上定義一個特性名-值對。
-find filename
指定Ant 應當處理的構建文件。與-buildfile 選項不一樣,若是所指定文件在當
前目錄中未找到,-find 就要求Ant 在其父目錄中再進行搜索。這種搜索會繼
續在其祖先目錄中進行,直至達到文件系統的根爲止,在此若是文件還未找
到,則構建失敗。
構建文件輪廓
下面是一個通用的構建文件,它很適合做爲一個模板。構建文件包括<project>
元素,以及其中嵌套的<target>、<property> 和<path> 元素。
<project default="all">
<property name="a.property" value="a value"/>
<property name="b.property" value="b value"/>
<path id="a.path">
<pathelement location="${java.home}/jre/lib/rt.jar"/>
</path>
<target name="all">
<javac srcdir=".">
<classpath refid="a.path"/>
</javac>
</target>
</project>
關於構建文件有幾點須要記住:
● 全部構建文件都要有<project>元素,並且至少有一個<target> 元素。
● 對於<project> 元素的default 屬性並無默認值。
● 構建文件並不必定要被命名爲build.xml。不過build.xml 是Ant 要搜索的默
認文件名。
● 每一個構建文件只能有一個<project> 元素。
例子
ant
使用當前目錄下的build.xml運行Ant,執行缺省的target。
ant -buildfile test.xml
使用當前目錄下的test.xml運行Ant,執行缺省的target。
ant -buildfile test.xml dist
使用當前目錄下的test.xml運行Ant,執行一個叫作dist的target。
ant -buildfile test.xml -Dbuild=build/classes dist
使用當前目錄下的test.xml運行Ant,執行一個叫作dist的target,並設定build屬性的值爲build/classes。
3編寫build.xml
Ant的buildfile是用XML寫的。每一個buildfile含有一個project。
buildfile中每一個task元素能夠有一個id屬性,能夠用這個id值引用指定的任務。這個值必須是惟一的。(詳情請參考下面的Task小節)
3.1Projects
project有下面的屬性:
AttributeDescriptionRequired
name項目名稱.No
default當沒有指定target時使用的缺省targetYes
basedir用於計算全部其餘路徑的基路徑。該屬性能夠被basedir property覆蓋。當覆蓋時,該屬性被忽略。若是屬性和basedir property都沒有設定,就使用buildfile文件的父目錄。No
項目的描述以一個頂級的<description>元素的形式出現(參看description小節)。
一個項目能夠定義一個或多個target。一個target是一系列你想要執行的。執行Ant時,你能夠選擇執行那個target。當沒有給定target時,使用project的default屬性所肯定的target。
3.2Targets
一個target能夠依賴於其餘的target。例如,你可能會有一個target用於編譯程序,一個target用於生成可執行文件。你在生成可執行文件以前必須先編譯經過,因此生成可執行文件的target依賴於編譯target。Ant會處理這種依賴關係。
然而,應當注意到,Ant的depends屬性只指定了target應該被執行的順序-若是被依賴的target沒法運行,這種depends對於指定了依賴關係的target就沒有影響。
Ant會依照depends屬性中target出現的順序(從左到右)依次執行每一個target。然而,要記住的是隻要某個target依賴於一個target,後者就會被先執行。
<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
假定咱們要執行target D。從它的依賴屬性來看,你可能認爲先執行C,而後B,最後A被執行。錯了,C依賴於B,B依賴於A,因此先執行A,而後B,而後C,最後D被執行。
一個target只能被執行一次,即時有多個target依賴於它(看上面的例子)。
若是(或若是不)某些屬性被設定,才執行某個target。這樣,容許根據系統的狀態(java version, OS, 命令行屬性定義等等)來更好地控制build的過程。要想讓一個target這樣作,你就應該在target元素中,加入if(或unless)屬性,帶上target因該有所判斷的屬性。例如:
<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>
若是沒有if或unless屬性,target總會被執行。
可選的description屬性可用來提供關於target的一行描述,這些描述可由-projecthelp命令行選項輸出。
將你的tstamp task在一個所謂的初始化target是很好的作法,其餘的target依賴這個初始化target。要確保初始化target是出如今其餘target依賴表中的第一個target。在本手冊中大多數的初始化target的名字是"init"。
target有下面的屬性:
AttributeDescriptionRequired
nametarget的名字Yes
depends用逗號分隔的target的名字列表,也就是依賴表。No
if執行target所須要設定的屬性名。No
unless執行target須要清除設定的屬性名。No
description關於target功能的簡短描述。No
3.3Tasks
一個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。
3.4Properties
一個project能夠有不少的properties。能夠在buildfile中用property task來設定,或在Ant以外設定。一個property有一個名字和一個值。property可用於task的屬性值。這是經過將屬性名放在"{"和"}"之間並放在屬性值的位置來實現的。例如若是有一個property builddir的值是"build",這個property就可用於屬性值:{builddir}/classes。這個值就可被解析爲build/classes。
內置屬性
若是你使用了<property> task 定義了全部的系統屬性,Ant容許你使用這些屬性。例如,{os.name}對應操做系統的名字。
要想獲得系統屬性的列表可參考the Javadoc of System.getProperties。
除了Java的系統屬性,Ant還定義了一些本身的內置屬性:
basedir project基目錄的絕對路徑 (與<project>的basedir屬性同樣)。
ant.file buildfile的絕對路徑。
ant.version Ant的版本。
ant.project.name 當前執行的project的名字;由<project>的name屬性設定.
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>
3.5Path-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}"/>
命令行變量
有些task可接受參數,並將其傳遞給另外一個進程。爲了能在變量中包含空格字符,可以使用嵌套的arg元素。
AttributeDescriptionRequired
value一個命令行變量;可包含空格字符。只能用一個
line空格分隔的命令行變量列表。
file做爲命令行變量的文件名;會被文件的絕對名替代。
path一個做爲單個命令行變量的path-like的字符串;或做爲分隔符,Ant會將其轉變爲特定平臺的分隔符。
例子
<arg value="-l -a"/>
是一個含有空格的單個的命令行變量。
<arg line="-l -a"/>
是兩個空格分隔的命令行變量。
<arg path="/dir;/dir2:\dir3"/>
是一個命令行變量,其值在DOS系統上爲\dir;\dir2;\dir3;在Unix系統上爲/dir:/dir2:/dir3 。
References
buildfile元素的id屬性可用來引用這些元素。若是你須要一遍遍的複製相同的XML代碼塊,這一屬性就頗有用--如屢次使用<classpath>結構。
下面的例子:
<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也接受這種類型的引用。
4Ant的Core Tasks
4.1File(Directory)類
4.1.1Mkdir
建立一個目錄,若是他的父目錄不存在,也會被同時建立。
例子:
<mkdir dir="build/classes"/>
說明:若是build不存在,也會被同時建立
4.1.2Copy
拷貝一個(組)文件、目錄
例子:
1.拷貝單個的文件:
<copy file="myfile.txt" tofile="mycopy.txt"/>
2.拷貝單個的文件到指定目錄下
<copy file="myfile.txt" todir="../some/other/dir"/>
3.拷貝一個目錄到另一個目錄下
<copy todir="../new/dir">
<fileset dir="src_dir"/>
</copy>
4.拷貝一批文件到指定目錄下
<copy todir="../dest/dir">
<fileset dir="src_dir">
<include name="**/*.java"/>
<iexclude name="**/Test.java"/>
</fileset>
</copy>
<copy todir="../dest/dir">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
5.拷貝一批文件到指定目錄下,將文件名後增長。Bak後綴
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<mapper type="glob" from="*" to="*.bak"/>
</copy>
6.拷貝一組文件到指定目錄下,替換其中的@標籤@內容
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<filterset>
<filter token="TITLE" value="Foo Bar"/>
</filterset>
</copy>
4.1.3Delete
刪除一個(組)文件或者目錄
例子
1.刪除一個文件
<delete file="/lib/ant.jar"/>
2.刪除指定目錄及其子目錄
<delete dir="lib"/>
3.刪除指定的一組文件
<delete>
<fileset dir="." includes="**/*.bak"/>
</delete>
4.刪除指定目錄及其子目錄,包括他本身
<delete includeEmptyDirs="true">
<fileset dir="build"/>
</delete>
4.1.4Move
移動或重命名一個(組)文件、目錄
例子:
1.移動或重命名一個文件
<move file="file.orig" tofile="file.moved"/>
2.移動或重命名一個文件到另外一個文件夾下面
<move file="file.orig" todir="dir/to/move/to"/>
3.將一個目錄移到另一個目錄下
<move todir="new/dir/to/move/to">
<fileset dir="src/dir"/>
</move>
4.將一組文件移動到另外的目錄下
<move todir="some/new/dir">
<fileset dir="my/src/dir">
<include name="**/*.jar"/>
<exclude name="**/ant.jar"/>
</fileset>
</move>
5.移動文件過程當中增長。Bak後綴
<move todir="my/src/dir">
<fileset dir="my/src/dir">
<exclude name="**/*.bak"/>
</fileset>
<mapper type="glob" from="*" to="*.bak"/>
</move>
4.2Java相關
4.2.1Javac
編譯java原代碼
例子
1.<javac srcdir="{src}"
destdir="{build}"
classpath="xyz.jar"
debug="on"
/>
編譯{src}目錄及其子目錄下的全部。Java文件,。Class文件將放在{build}指定的目錄下,classpath表示須要用到的類文件或者目錄,debug設置爲on表示輸出debug信息
2.<javac srcdir="{src}:{src2}"
destdir="{build}"
includes="mypackage/p1/**,mypackage/p2/**"
excludes="mypackage/p1/testpackage/**"
classpath="xyz.jar"
debug="on"
/>
編譯{src}和{src2}目錄及其子目錄下的全部。Java文件,可是package/p1/**,mypackage/p2/**將被編譯,而mypackage/p1/testpackage/**將不會被編譯。Class文件將放在{build}指定的目錄下,classpath表示須要用到的類文件或者目錄,debug設置爲on表示輸出debug信息
3.<property name="classpath" value=".;./xml-apis.jar;../lib/xbean.jar;./easypo.jar"/>
<javac srcdir="{src}"
destdir="{src}"
classpath="{classpath}"
debug="on"
/>
路徑是在property中定義的
4.2.2java
執行指定的java類
例子:
1.<java classname="test.Main">
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="{java.class.path}"/>
</classpath>
</java>
classname中指定要執行的類,classpath設定要使用的環境變量
2.<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>
4.3打包相關
4.3.1jar
將一組文件打包
例子:
1.<jar destfile="{dist}/lib/app.jar" basedir="{build}/classes"/>
將{build}/classes下面的全部文件打包到{dist}/lib/app.jar中
2.<jar destfile="{dist}/lib/app.jar"
basedir="{build}/classes"
includes="mypackage/test/**"
excludes="**/Test.class"
/>
將{build}/classes下面的全部文件打包到{dist}/lib/app.jar中,可是包括mypackage/test/全部文件不包括全部的Test.class
3.<jar destfile="{dist}/lib/app.jar"
basedir="{build}/classes"
includes="mypackage/test/**"
excludes="**/Test.class"
manifest="my.mf"
/>
manifest屬性指定本身的META-INF/MANIFEST.MF文件,而不是由系統生成
4.3.2war
對Jar的擴展,用於打包Web應用
例子:
假設咱們的文件目錄以下:
thirdparty/libs/jdbc1.jar
thirdparty/libs/jdbc2.jar
build/main/com/myco/myapp/Servlet.class
src/metadata/myapp.xml
src/html/myapp/index.html
src/jsp/myapp/front.jsp
src/graphics/images/gifs/small/logo.gif
src/graphics/images/gifs/large/logo.gif
下面是咱們的任務的內容:
<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>
完成後的結果:
WEB-INF/web.xml
WEB-INF/lib/jdbc2.jar
WEB-INF/classes/com/myco/myapp/Servlet.class
META-INF/MANIFEST.MF
index.html
front.jsp
images/small/logo.gif
images/large/logo.gif
4.3.3ear
用於打包企業應用
例子
<ear destfile="{build.dir}/myapp.ear" appxml="{src.dir}/metadata/application.xml">
<fileset dir="{build.dir}" includes="*.jar,*.war"/>
</ear>
4.4時間戳
在生成環境中使用當前時間和日期,以某種方式標記某個生成任務的輸出,以便記錄它是什麼時候生成的,這常常是可取的。這可能涉及編輯一個文件,以便插入一個字符串來指定日期和時間,或將這個信息合併到 JAR 或 zip 文件的文件名中。
這種須要是經過簡單可是很是有用的 tstamp 任務來解決的。這個任務一般在某次生成過程開始時調用,好比在一個 init 目標中。這個任務不須要屬性,許多狀況下只需 <tstamp/> 就足夠了。
tstamp 不產生任何輸出;相反,它根據當前系統時間和日期設置 Ant 屬性。下面是 tstamp 設置的一些屬性、對每一個屬性的說明,以及這些屬性可被設置到的值的例子:
屬性說明例子
DSTAMP 設置爲當前日期,默認格式爲yyyymmdd 20031217
TSTAMP 設置爲當前時間,默認格式爲 hhmm 1603
TODAY 設置爲當前日期,帶完整的月份2003 年 12 月 17 日
例如,在前一小節中,咱們按以下方式建立了一個 JAR 文件:
<jar destfile="package.jar" basedir="classes"/>
在調用 tstamp 任務以後,咱們可以根據日期命名該 JAR 文件,以下所示:
<jar destfile="package-{DSTAMP}.jar" basedir="classes"/>
所以,若是這個任務在 2003 年 12 月 17 日調用,該 JAR 文件將被命名爲 package-20031217.jar。
還能夠配置 tstamp 任務來設置不一樣的屬性,應用一個當前時間以前或以後的時間偏移,或以不一樣的方式格式化該字符串。全部這些都是使用一個嵌套的 format 元素來完成的,以下所示:
<tstamp>
<format property="OFFSET_TIME"
pattern="HH:mm:ss"
offset="10" unit="minute"/>
</tstamp>
上面的清單將 OFFSET_TIME 屬性設置爲距離當前時間 10 分鐘以後的小時數、分鐘數和秒數。
用於定義格式字符串的字符與 java.text.SimpleDateFormat 類所定義的那些格式字符相同
4.5執行SQL語句
經過jdbc執行SQL語句
例子:
1.<sql
driver="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost:3306/mydb"
userid="root"
password="root"
src="data.sql"
/>
2.<sql
driver="org.database.jdbcDriver"
url="jdbc:database-url"
userid="sa"
password="pass"
src="data.sql"
rdbms="oracle"
version="8.1."
>
</sql>
只有在oracle、版本是8.1的時候才執行
4.6發送郵件
使用SMTP服務器發送郵件
例子:
<mail mailhost="smtp.myisp.com" mailport="1025" subject="Test build">
<from address="me@myisp.com"/>
<to address="all@xyz.com"/>
<message>The {buildname} nightly build has completed</message>
<fileset dir="dist">
<includes name="**/*.zip"/>
</fileset>
</mail>
mailhost: SMTP服務器地址
mailport:服務器端口
subject:主題
from:發送人地址
to:接受人地址
message:發送的消息
fileset:設置附件
-. Ant簡介
Ant是一款相似make的工具,用來編譯/運行/打包Java程序。在構建、包裝和發佈過程
中幾乎每一件事均可以由Ant的任務來處理。
二.搭建ANT運行環境
一、將ant1.6.1解壓縮到任意目錄,假設解壓縮到C:\apache-ant-1.6.1目錄中
二、而後在path路徑中添加 C:\apache-ant-1.6.1\bin
三、再classpath中添加 C:\apache-ant-1.6.1\lib
3、ANT的組成(主要由三部分組成:Project、Target、Task)
一、Project(項目)。基本屬性:name、default、basedir。一個build.xml只能存在一個Project工程。
name :項目名稱
default :缺省開始執行的Target
basedir :用於計算全部其餘路徑的基路徑。
例1:<project name="dev" basedir="." default="dist">
二、Target。一個項目能夠定義一個或多個Target、一個Target是一系列你想要執行的任務,如編譯任務、打包任務、混淆任務。
Target的基本屬性: name:target的名字,depends:該target依賴關係,description: target的描述信息。
例2:<target name="clean" depends="init" description="Clean dist and temp directories">
Ant在執行時以Target爲單位,Target的depends屬性又決定了哪一個Target先執行,所以咱們能夠經過Target來構造編譯順序。
例3:<target name="copy" >
<target name="javac" depends="copy">
<target name="jar" depends="javac">
執行順序是從下至上,依次執行,若是某個Target沒有depends屬性,那麼就順序執行。
例4:一個完整的Target:
<target name="compile" depends="replacesrc" description="Compiling Java source files">
<javac srcdir="temp/src"
destdir="temp/build"
debug="on"
deprecation="false"
optimize="true">
<classpath refid="classpath"/>
</javac>
</target>
三、Task。Ant執行的一系列任務是由Target構成的,而Target又是由數個小的Task構成的,task任務是最小的運行單位,咱們能夠把copy、delete、mkdir等操做認爲是一個小任務。
(1)copy任務。
A.拷貝單個文件:
<copy file="Demo/manifest.mf" todir="temp/build/META-INF" />
解釋:把一個文件拷貝到拷貝相關文件夾中。
B.拷貝文件夾:
<copy todir="temp/build">
<fileset dir="temp/classes"/>
</copy>
解釋:把temp/build目錄下的全部文件,拷貝到temp/classes目錄中去
C.替換拷貝
<copy todir="temp/build">
<fileset dir="temp/classes" includes="*.class" />
<filterset>
<filter token="@Time@" value="${app.time}"/>
</filterset>
</copy>
解釋: <filterset>過濾集,能夠將temp/classes文件夾下的存在@Time@標記的文件,替換爲變量${app.time}值。這樣在完成拷貝的同時也完成了替換任務。
(2)mkdir任務和delete任務
A.單獨的delete和mkdir任務
<delete dir="temp/src"/>
<delete file="temp/build/Thumbs.db" />
<mkdir dir="temp/src"/>
B. 帶有條件的刪除任務
<delete>
<fileset dir="store" includes="*.*"/>
<fileset dir="source" excludes="*.java"/> </delete>
解釋:include表示要刪除哪些文件;而excludes表示排除的文件;
(3)replace替換任務
A.替換某一文件中的字符串
<replace file ="base/testing.txt">
token="@temp@"
value="${newstring}"
</replace>
解釋:token是須要替換的標記;value是新值,將testing.txt文件中的@temp@替換爲新值。
B.替換某個文件夾中存在特定標記的文件
<replace dir="temp" token="@CHARSET@" value="${webapp.charset}"/>
解釋:temp目錄中文件,若是有存在@CHARSET@標記的,將被替換爲${webapp.charset}變量值。
C.批量替換
<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>
(4) javac任務 ,編譯源程序
<target name="Compile" description="Compile Java source files">
<javac srcdir="src"
destdir="temp/classes"
bootclasspath="${compile.classpath}"
target="1.1"
debug="on"
deprecation="on"
includes="*.java"
optimize="true"
encoding="UTF-8"/>
</target>
解釋:bootclasspath參數(啓動類庫):它已經包含了jre/lib目錄下的rt.jar,以及咱們自定義的類庫。若是使用classpath參數,僅指咱們定義的類庫;
(5) java任務 。爲運行Java應用程序,須要使用java任務
A.運行一個類
<target name="run" description="Run the program">
<java classname="${main}" classpath="${classpath}"/>
</target>
解釋:classname表示要運行的主類。
B.運行某一特定類,並加上運行參數。
<java fork="true" classname="proguard.ProGuard" classpath="${proguard.classpath}">
<arg line="-libraryjars ${proguard.classpath}"/>
<arg line="-injars temp/${app.project}_tmp.jar"/>
<arg line="-outjar temp/${app.project}_obf.jar"/>
<arg line="-defaultpackage ''"/>
<arg line="-dontusemixedcaseclassnames"/>
<arg line="-keep public class ${app.midlet}"/>
</java>
解釋:fork參數:爲true時,在新的JVM實例中運行,不影響當前JVM工做
如何減小文件的size?
使用3.3.2版本的proguard.jar,而後在混淆參數中添加兩行代碼:
<arg line = "-overloadaggressively"/>
<arg line="-keepclasseswithmembers public class ${app.midlet} {public void startApp();public void destroyApp(boolean);}"/>
這樣能夠保證startApp和destroyApp不被打上Final修飾符,同時還能更大的壓縮代碼,不過要求Midlet類中startApp和destroyApp方法保持上面的形式。
(6)JAR任務
將編譯好的CLASS文件打成JAR包,這是JAR任務的工做:
<target name="jar" depends="Compile" description="Build jar file">
<jar jarfile="dist/${name}.jar"
basedir="${tmp/class}"
manifest="tmp/res/manifest.mf"
manifestencoding="UTF-8">
<fileset dir="res" includes="*.*"/> <!-- 將res目錄中的文件也打進JAR包 -->
</jar>
</target>
(7)exec任務,用以調用外部程序
<exec executable="${LIB_PATH}/preverify.exe">
<arg line="-classpath ${compile.classpath} -d temp/build temp/obfuscate"/>
</exec>
4、ANT的參數部分:
-quiet(不顯示大多數build信息)
-verbose(顯示構建過程的每一個操做的詳細信息)
-buildfile filename.xml 構建特定的xml文件
-Dproperty=value 設定特別的外部參數,外部參數能夠傳遞給內部變量
-find filename.xml 它會讓ANT自動查找當前的目錄、父目錄中的xml文件,直到失敗
例:
ant -buildfile test.xml
使用當前目錄下的test.xml運行Ant
ant -buildfile test.xml dist
使用當前目錄下的test.xml運行Ant,執行一個叫作dist的target。
ant -buildfile test.xml -Dbuild=build/classes dist
使用當前目錄下的test.xml運行Ant,執行一個叫作dist的target,並設定build變量的值爲build/classes。
5、自定義TASK
ANT已經內置了很多task,像copy、replace、javac等等,可是有時候還須要一些特定的任務來完成操做,好比在生成JAD文件時,須要一個Midlet-Jar-Size的參數,獲得JAR文件的大小,可是經過內部的task沒法實現,所以能夠本身編寫類來實現此功能,但必須保證該類是從Task類繼承過來的。
例:
<taskdef name="filesize" classname="ant.FileSizeTask" classpath="${LIB_PATH}/FileSizeTask.jar" />
<filesize file="${Base}/Demo_Build/${jarName}" property="size" />
<replace dir="store" includes="${jadName}" encoding="UTF-8">
<replacefilter token="@FILESIZE@" value="${size}" />
</replace>
解釋:taskdef:自定義任務,name:任務名
編寫Ant 自定義任務很簡單,Ant 可以使用生成文件中指定的對應屬性的值來調用這個方法,這個方法的名稱須要是 set 加上屬性的名稱,所以在下面的例子中,咱們須要名爲 setFile() 和 setTofile() 的兩個方法。
當 Ant 遇到生成文件中的一個屬性設置時,它會尋找相關任務中具備適當名稱的方法(稱爲 setter 方法)。
生成文件中的屬性是做爲字符串來指定的,所以咱們的 setter 方法的參數能夠是一個字符串。在這樣的狀況下,Ant 將在展開值所引用的任何屬性以後,使用該屬性的字符串值來調用咱們的方法。
但有時咱們想把屬性的值看做是一種不一樣的類型。這裏的示例任務就是這種狀況,其中的屬性值引用文件系統上的文件,而不僅是引用任意的字符串。能夠經過將方法參數聲明爲 java.io.File 類型來容易地作到這點。
Ant 將接受屬性的字符串值,並把它解釋爲一個文件,而後傳遞給咱們的方法。Ant 可以對其餘類型執行相似的轉換,好比 boolean 和 int 類型。但若是提供具備相同名稱可是具備不一樣參數的兩個方法,Ant 將使用更明確的那一個方法,所以文件類型將優先於字符串類型。
例:一個排序的task任務
public class FileSorter extends Task {
private File file, tofile;
// ant在進行任務處理時會調用execute()方法
public void execute() throws BuildException {
System.out.println("Sorting file="+file);
try {
BufferedReader from =
new BufferedReader(new FileReader(file));
BufferedWriter to =
new BufferedWriter(new FileWriter(tofile));
List allLines = new ArrayList();
// read in the input file
String line = from.readLine();
while (line != null) {
allLines.add(line);
line = from.readLine();
}
from.close();
// sort the list
Collections.sort(allLines);
// write out the sorted list
for (ListIterator i=allLines.listIterator(); i.hasNext(); ) {
String s = (String)i.next();
to.write(s); to.newLine();
}
to.close();
} catch (FileNotFoundException e) {
throw new BuildException(e);
} catch (IOException e) {
throw new BuildException(e);
}
}
// file參數
public void setFile(File file) {
this.file = file;
}
// tofile參數
public void setTofile(File tofile) {
this.tofile = tofile;
}
}
使用這個自定義任務:
<taskdef name="filesorter" classname=" FileSorter" classpath="filesorter"/>
<target name="main">
<filesorter file="input.txt" tofile="output.txt"/>
</target>
解釋:file和tofile分別是程序入口、出口