Ant是一個Apache基金會下的跨平臺的構建工具,它是一個將軟件編譯、測試、部署等步驟聯繫在一塊兒加以自動化的一個工具。html
在本文中,我主要讓介紹Ant的命令、構建文件、最後部分以一個實例概述在持續集成工具jenkins中的應用。java
開發過程當中,咱們通常是在windows下,利用eclipse能夠很輕鬆地實現一鍵編譯、測試、打包、部署,可是咱們的應用通常是部署在linux下,咱們不可能安裝一個eclipse在linux上。那linux上有沒有相似eclipse這樣的工具呢?答案是確定的,這個工具就是Ant,使用它能夠實現自動化部署。除此以外,它還有不少優勢。linux
一、跨平臺性:Ant是純Java語言編寫的,因此具備很好的跨平臺性。
二、操做簡單:Ant運行時使用一個XML文件(構建文件)。 Ant經過調用target樹,就能夠執行各類task。每一個task實現了特定接口對象。
三、集成方便:使用Ant就是搭建了一個一致的配置環境,每次集成都經過Ant自動化的構建(包括編譯,發佈,自動化測試)來驗證,從而儘早地發現集成錯誤。web
比較簡單,這裏請參見「使用jenkins實現持續集成V2.pdf」 2.2說明,注意安裝好以後要配置下環境變量。windows
參見個人這篇文章:使用jenkins實現持續集成(http://www.cnblogs.com/zishengY/p/7170656.html)app
Ant的構件文件是基於XML編寫的,默認build.xml就是主要的ant腳本。
ant
在當前目錄下的build.xml運行Ant,執行缺省的target。less
ant -buildfile build-test.xml
在當前目錄下的build-test.xml運行Ant,執行缺省的target。eclipse
ant -buildfile build-test.xml clean
在當前目錄下的build-test.xml運行Ant,執行一個叫作clean的target。jvm
ant -buildfile build-test.xml -Dbuild=build/classes clean
在當前目錄下的build-test.xml運行Ant,執行一個叫作clean的target,並設定build屬性的值爲build/classes。jsp
參見「http://blog.csdn.net/D3Direct_1/article/details/53055236」
本部分主要介紹Ant構建文件(默認是是build.xml)的元素組成。
一、project 節點元素
project 元素是 Ant 構件文件的根元素, Ant 構件文件至少應該包含一個 project 元素,不然會發生錯誤。在每一個 project 元素下,可包含多個 target 元素。接下來向讀者展現一下 project 元素的各屬性。
● name 屬性:用於指定 project 元素的名稱。
● default 屬性:用於指定 project 默認執行的target 的名稱。
● basedir 屬性:用於指定基路徑的位置。該屬性沒有指定時,使用 Ant 的構件文件的附目錄做爲基準目錄。
<?xml version="1.0" ?><project name="ant-project" default="print-dir" basedir="."><target name="print-dir"><echo message="The base dir is: ${basedir}" /></target></project>
從上例能夠看出,在這裏定義了default 屬性的值爲print-dir,即當運行ant 命令時,若是沒有指明執行的target,則將執行默認的target(print-dir)。此外,還定義了basedir 屬性的值爲 「.」 ,.表示當前目錄,進入當前目錄後運行ant 命令,得一下結果:
二、target節點元素
target爲ant的基本執行單元或是任務,它能夠包含一個或多個具體的單元/任務。多個target 能夠存在相互依賴關係。它有以下屬性:
● name 屬性:指定 target 元素的名稱,這個屬性在一個 project 元素中是惟一的。咱們能夠經過指定 target 元素的名稱來指定某個 target 。
● depends 屬性:用於描述 target 之間的依賴關係,若與多個 target 存在依賴關係時,須要以「,」間隔。 Ant 會依照 depends 屬性中 target 出現的順序依次執行每一個 target ,被依賴的target 會先執行。
● if 屬性:用於驗證指定的屬性是存在,若不存在,所在 target 將不會被執行。
● unless 屬性:該屬性的功能與 if 屬性的功能正好相反,它也用於驗證指定的屬性是否存在,若不存在,所在 target 將會被執行。
● description 屬性:該屬性是關於 target 功能的簡短描述和說明。
示例:
<?xml version="1.0" ?><project name="ant-target" default="print"><target name="version" if="ant.java.version"><echo message="Java Version: ${ant.java.version}" /></target><target name="print" depends="version" unless="docs"><description>a depend example!</description><echo message="The base dir is: ${basedir}" /></target></project>
從如下結果後能夠看到,咱們運行的是名爲 print的target ,因爲它依賴於version這個target任務,因此 version將首先被執行,同時由於系統配置了JDK,因此 ant.java.version 屬性存在,執行了version,輸出信息:"[echo] Java Version: 1.6 ",version執行完畢後,接着執行 print,由於docs不存在,而unless屬性是在不存在時進入所在target 的,由此可知 print得以執行,輸出信息:"[echo] The base dir is:D:\Workspace\AntExample\build"。
三、property屬性節點元素
property元素可看做參量或者參數的定義,project 的屬性能夠經過 property 元素來設定,也可在 Ant 以外設定。若要在外部引入某文件,例如 build.properties 文件,能夠經過以下內容將其引:
<property file="build.properties"/>
property 元素可用做 task 的屬性值。在 task 中是經過將屬性名放在${屬性名}之間,並放在 task 屬性值的位置來實現的。
Ant 提供了一些內置的屬性,它能獲得的系統屬性的列表與 Java 文檔中 System.getProperties() 方法獲得的屬性一致,這些系統屬性可參考 sun 網站的說明。同時, Ant 還提供了一些它本身的內置屬性,以下:
basedir: project 基目錄的絕對路徑;
ant.file: buildfile的絕對路徑,上例中ant.file值爲D:\Workspace\AntExample\build;
ant.version: Ant 的版本信息,本文爲1.8.1 ;
ant.project.name: 當前指定的project的名字,即前文說到的project的name屬性值;
ant.java.version: Ant 檢測到的JDK版本,本文爲 1.6 。舉例說明以下:
<project name="ant-project" default="example"><property name="name" value="jojo" /><property name="age" value="25" /><target name="example"><echo message="name: ${name}, age: ${age}" /></target></project>
上例中用戶設置了名爲name 和age的兩個屬性,這兩個屬性設置後,在下文中能夠經過 ${name} 和 ${age} 分別取得這兩個屬性值。
四、copy命令
copy主要用來對文件和目錄的複製功能。舉例以下:
● 複製單個文件:
<copy file="old.txt" tofile="new.txt"/>● 對文件目錄進行復制:
<copy todir="../dest_dir">
<fileset dir="src_dir"/>
</copy>● 將文件複製到另外的目錄:
<copy file="src.txt" todir="c:/base"/>
五、delete命令
對文件或目錄進行刪除,舉例以下:
● 刪除某個文件:
<delete file="/res/image/cat.jpg"/>● 刪除某個目錄:
<delete dir="/res/image"/>● 刪除全部的jar文件或空目錄:
<delete includeEmptyDirs="true">
<fileset dir="." includes="**/*.jar"/>
</delete>
六、 mkdir 命令
建立目錄。
<mkdir dir="/home/philander/build/classes"/>
七、 move 命令
移動文件或目錄,舉例以下:
● 移動單個文件:
<move file="sourcefile" tofile=」destfile」/>● 移動單個文件到另外一個目錄:
<move file="sourcefile" todir=」movedir」/>● 移動某個目錄到另外一個目錄:
<move todir="newdir">
<fileset dir="olddir"/>
</move>
八、echo 命令
該任務的做用是根據日誌或監控器的級別輸出信息。它包括 message 、 file 、 append 和 level 四個屬性,舉例以下
<echo message="ant message" file="/logs/ant.log" append="true">
九、jar 標籤節點元素
該標籤用來生成一個JAR文件,其屬性以下。
● destfile表示JAR文件名。
● basedir表示被歸檔的文件名。
● includes表示別歸檔的文件模式。
● exchudes表示被排除的文件模式。● compress表示是否壓縮。
示例:
<jar destfile="${webRoot}/${ash_jar}" level="9" compress="true" encoding="utf-8" basedir="${dest}"><manifest><attribute name="Implementation-Version" value="Version: 2.2"/></manifest></jar>
上面的mainfest是jar包中的MEAT-INF中的MANIFEST.MF中的文件內容
一樣打包操做的的還有war、tgz,已經解壓操做uzip
<!-- 建立zip --><zip basedir="${basedir}\classes" zipfile="temp\output.zip"/><!-- 建立tgz --><gzip src="classes\**\*.class" zipfile="output.class.gz"/><!-- 解壓zip --><unzip src="output.class.gz" dest="extractDir"/><!-- 創建war包 --><war destfile="${webRoot}/ash.war" basedir="${basedir}/web" webxml="${basedir}/web/WEB-INF/web.xml"><exclude name="WEB-INF/classes/**"/><exclude name="WEB-INF/lib/**"/><exclude name="WEB-INF/work/_jsp/**"/><lib dir="${lib.dir}" includes="**/*.jar, **/*.so, **/*.dll"><exclude name="${webRoot}\${helloworld_jar}"/></lib><lib file="${webRoot}/${helloworld_jar}"/><classes dir="${dest}" includes="**/*.xml, **/*.properites, **/*.xsd"> </classes></war>
十、javac 標籤節點元素
該標籤用於編譯一個或一組java文件,其屬性以下。
● srcdir表示源程序的目錄。
● destdir表示class文件的輸出目錄。
● include表示被編譯的文件的模式。
● excludes表示被排除的文件的模式。
● classpath表示所使用的類路徑。
● debug表示包含的調試信息。
● optimize表示是否使用優化。
● verbose 表示提供詳細的輸出信息。
● fileonerror表示當碰到錯誤就自動中止。示例
<javac srcdir="${src}" destdir="${dest}"/><!-- 設置jvm內存<javac srcdir="src" fork="true"/><javac srcdir="src" fork="true" executable="d:\sdk141\bin\javac"memoryMaximumSize="128m"/>-->
十一、java 標籤節點元素
該標籤用來執行編譯生成的.class文件,其屬性以下。
● classname 表示將執行的類名。
● jar表示包含該類的JAR文件名。
● classpath所表示用到的類路徑。
● fork表示在一個新的虛擬機中運行該類。
● failonerror表示當出現錯誤時自動中止。
● output 表示輸出文件。
● append表示追加或者覆蓋默認文件。示例
<java classname="com.hoo.test.HelloWorld" classpath="${hello_jar}"/>
十二、arg 數據參數元素
由Ant構建文件調用的程序,能夠經過<arg>元素向其傳遞命令行參數,如apply,exec和java任務都可接受嵌套<arg>元素,能夠爲各自的過程調用指定參數。如下是<arg>的全部屬性。
● values 是一個命令參數。若是參數中有空格,但又想將它做爲單獨一個值,則使用此屬性。
● file 表示一個參數的文件名。在構建文件中,此文件名相對於當前的工做目錄。
● line 表示用空格分隔的多個參數列表。
● 表示路徑,一個做爲單個命令行變量的path-like的字符串;或做爲分隔符,Ant會將其轉變爲特定平臺的分隔符。
● pathref 引用的path(使用path元素節點定義path)的id
● prefix 前綴
● suffix 後綴例子
<arg value="-l -a"/>
是一個含有空格的單個的命令行變量。
<arg line="-l -a"/>
是兩個空格分隔的命令行變量。
<arg path="/dir;/dir2:\dir3"/>
是一個命令行變量,其值在DOS系統上爲\dir;\dir2;\dir3;在Unix系統上爲/dir:/dir2:/dir3 。
1三、ervironment 類型
由Ant構建文件調用的外部命令或程序,<env>元素制定了哪些環境變量要傳遞給正在執行的系統命令,<env>元素能夠接受如下屬性。
● file表示環境變量值的文件名。此文件名要被轉換位一個絕對路徑。
● path表示環境變量的路徑。Ant會將它轉換爲一個本地約定。
● value 表示環境變量的一個直接變量。
● key 表示環境變量名。
注意 file path 或 value只能取一個。
1四、filelist 文件集合列表
filelist 是一個支持命名的文件列表的數據類型,包含在一個filelist類型中的文件不必定是存在的文件。如下是其全部的屬性。
● dir是用於計算絕對文件名的目錄。
● files 是用逗號分隔的文件名列表。
● refid 是對某處定義的一個<filelist>的引用。
注意 dir 和 files 都是必要的,除非指定了refid(這種狀況下,dir和files都不容許使用)。示例
<filelist id="docfiles" dir="${doc.src}" files="foo.xml,bar.xml"/>文件集合 ${doc.src}/foo.xml和${doc.src}/bar.xml. 這些文件也許仍是不存在的文件.<filelist id="docfiles" dir="${doc.src}" files="foo.xml bar.xml"/><filelist refid="docfiles"/><filelist id="docfiles" dir="${doc.src}"><file name="foo.xml"/><file name="bar.xml"/></filelist>
1五、fileset 文件類型
fileset 數據類型定義了一組文件,並一般表示爲<fileset>元素。不過,許多ant任務構建成了隱式的fileset,這說明他們支持全部的fileset屬性和嵌套元素。如下爲fileset 的屬性列表。
● dir表示fileset 的基目錄。
● casesensitive的值若是爲false,那麼匹配文件名時,fileset不是區分大小寫的,其默認值爲true.
● defaultexcludes 用來肯定是否使用默認的排除模式,默認爲true。
● excludes 是用逗號分隔的須要派出的文件模式列表。
● excludesfile 表示每行包含一個排除模式的文件的文件名。
● includes 是用逗號分隔的,須要包含的文件模式列表。
● includesfile 表示每行包括一個包含模式的文件名。示例
<fileset id="lib.runtime" dir="${lib.path}/runtime"><include name="**/*.jar"/><include name="**/*.so"/><include name="**/*.dll"/></fileset><fileset id="lib.container" dir="${lib.path}/container"><include name="**/*.jar"/></fileset><fileset id="lib.extras" dir="${lib.path}"><include name="test/**/*.jar"/></fileset>
1六、patternset 類型
fileset 是對文件的分組,而patternset是對模式的分組,他們是緊密相關的概念。
<patternset>支持4個屬性:includes、excludex、includexfile、excludesfile,這些與fileset相同。
patternset 還容許如下嵌套元素:include,exclude,includefile 和 excludesfile.
示例
<!-- 黑白名單 --><patternset id="non.test.sources"><include name="**/*.java"/><!-- 文件名包含Test的排除 --><exclude name="**/*Test*"/></patternset><patternset id="sources"><include name="std/**/*.java"/><!-- 判斷條件 存在professional就引入 --><include name="prof/**/*.java" if="professional"/><exclude name="**/*Test*"/></patternset><!-- 一組文件 --><patternset includesfile="some-file"/><patternset><includesfile name="some-file"/><patternset/><patternset><includesfile name="some-file"/><includesfile name="${some-other-file}" if="some-other-file"/><patternset/>
1七、filterset 類型
filterset定義了一組過濾器,這些過濾器將在文件移動或複製時完成文件的文本替換。
主要屬性以下:
● begintoken 表示嵌套過濾器所搜索的記號,這是標識其開始的字符串。
● endtoken 表示嵌套過濾器所搜索的記號這是標識其結束的字符串。
● id 是過濾器的惟一標誌符。
● refid 是對構建文件中某處定義一個過濾器的引用。示例
<!-- 將目標文件build.dir目錄中的version.txt文件內容中的@DATE@替換成TODAY當前日期的值,並把替換後的文件存放在dist.dir目錄中 --><copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt"><filterset><filter token="DATE" value="${TODAY}"/></filterset></copy><!-- 自定義變量的格式 --><copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt"><!-- 從version.txt中的%位置開始搜索,到*位置結束,進行替換內容中的@DATE@替換成TODAY當前日期的值--><filterset begintoken="%" endtoken="*"><filter token="DATE" value="${TODAY}"/></filterset></copy><!-- 使用外部的過濾定義文件 --><copy toDir="${dist.dir}/docs"><fileset dir="${build.dir}/docs"><include name="**/*.html"></fileset><filterset begintoken="%" endtoken="*"><!-- 過來文件從外部引入,過來的屬性和值配置在dist.properties文件中 --><filtersfile file="${user.dir}/dist.properties"/></filterset></copy><!-- 使用引用方式,重複利用過濾集 --><filterset id="myFilterSet" begintoken="%" endtoken="*"><filter token="DATE" value="${TODAY}"/></filterset><copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt"><filterset refid="myFilterSet"/></copy>
1八、path類型
path元素用來表示一個類路徑,不過它還能夠用於表示其餘的路徑。在用做幾個屬性時,路經中的各項用分號或冒號隔開。在構建的時候,此分隔符將代替當前平臺中全部的路徑分隔符,其擁有的屬性以下。
● location 表示一個文件或目錄。Ant在內部將此擴展爲一個絕對路徑。
● refid 是對當前構建文件中某處定義的一個path的引用。
● path表示一個文件或路徑名列表。示例
<path id="buildpath"><fileset refid="lib.runtime"/><fileset refid="lib.container"/><fileset refid="lib.extras"/></path><path id="src.paths"><fileset id="srcs" dir="."><include name="src/**/*.java"/></fileset></path>
6、ant編譯打包、運行工程
<?xml version="1.0" encoding="UTF-8"?><!-- name是當前工程的名稱,default是默認執行的任務,basedir是工做目錄(.表明當前根目錄) --><project name="HelloWorld" default="run" basedir="."><!-- property相似於程序中定義簡單的變量 --><property name="src" value="src"/><property name="dest" value="classes"/><property name="hello_jar" value="helloWorld.jar"/><!--target是一個事件、事情、任務, name是當前事情的名稱,depends是依賴的上一件或是多件事情若是所依賴的事情沒有執行,ant會先運行依賴事情,而後再運行當前事情--><!-- 初始化 --><target name="init"><!-- 創建classes目錄 --><mkdir dir="${dest}"/><mkdir dir="temp"/><mkdir dir="temp2"/></target><!-- 編譯 --><target name="compile" depends="init"><javac srcdir="${src}" destdir="${dest}"/><!-- 設置jvm內存<javac srcdir="src" fork="true"/><javac srcdir="src" fork="true" executable="d:\sdk141\bin\javac"memoryMaximumSize="128m"/>--></target><!-- 創建jar包 --><target name="build" depends="compile"><!--<jar jarfile="${hello_jar}" basedir="${dest}"/>建立一個名稱是package.jar文件<jar destfile="package.jar" basedir="classes"/>--><jar destfile="${hello_jar}" basedir="classes"><!-- 向jar包中的main文件中添加內容 --><manifest><attribute name="Built-By" value="${user.name}"/><attribute name="Main-class" value="package.Main"/></manifest></jar><!-- 複製jar文件 todir="複製到目錄"--><copy file="${hello_jar}" tofile="${dest}\temp.jar"/><copy todir="temp"><!-- 不按照默認方式 defaultexcludes="" --><fileset dir="src"><include name="**/*.java"/></fileset></copy><copy todir="temp2"><fileset dir="src"><and><contains text="main"/><size value="1" when="more"/></and></fileset></copy><!-- 移動jar文件 --><move file="${dest}\temp.jar" tofile="temp\move-temp.jar"/><!-- 建立zip --><zip basedir="${basedir}\classes" zipfile="temp\output.zip"/><!-- 建立tgz --><gzip src="classes\**\*.class" zipfile="output.class.gz"/><!-- 解壓zip --><unzip src="output.class.gz" dest="extractDir"/><!--替換input.txt內容中的old爲new<replace file="input.txt" token="old" value="new"/>--></target><!-- 運行 --><target name="run" depends="build"><java classname="com.hoo.test.HelloWorld" classpath="${hello_jar}"/></target><!-- 清除 --><target name="clean"><!-- 刪除生成的文件 --><delete dir="${dest}"/><delete file="${hello_jar}"/></target><tstamp><format property="OFFSET_TIME"pattern="HH:mm:ss"offset="10" unit="minute"/></tstamp><!-- 從新運行 --><target name="rerun" depends="clean,run"><echo message="###${TSTAMP}#${TODAY}#${DSTAMP}###"/><aunt target="clean"/><aunt target="run"/></target></project>
要說的的東西基本上就那麼多,ant還有不少內容沒有提到,有興趣的能夠本身去研究研究。ant不難,你用它就像是在docs控制檯輸入命令行同樣,只不過ant是將命令行轉換爲xml的腳本信息,能夠進行重複的運行。在必定狀況下,提升了效率和重複的工做。