1. 程式人生 > >1、自動構建工具Ant初步

1、自動構建工具Ant初步

Ant是什麼?——Apache Ant是一個基於Java的生成工具。據最初的創始人James Duncan Davidson介紹,這個工具的名稱是another neat tool(另一個整潔的工具)的首字母縮寫。

從Apache網站下載ant:1.9.2版本,apache-ant-1.9.2-bin.zip,解壓縮後,有四個資料夾和幾個檔案,四個資料夾分別是:bin、lib、etc、manual,假如加壓縮的後放在D:\apache-ant-1.9.2\,我們需要在windows的環境變數中path新增bin的路徑,新增完畢後,執行ant,在我的環境中出現了以下異常:

Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/to
ols/ant/launch/Launcher (Unsupported major.minor version 48.0)
        at java.lang.ClassLoader.defineClass0(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
出現的原因,是自己的機器上曾經安裝過oracle,而oracle有自己的jre,是1.3版本的,將path中的C:\Program Files\Oracle\jre\1.3.1\bin;去掉,使用安裝的jdk1.6路徑,執行正常了,

C:\Documents and Settings\Administrator>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: build.xml does not exist!
Build failed

1、Ant的作用

生成工具在軟體開發中用來將原始碼和其他輸入檔案轉換為可執行檔案的形式(也有可能轉換為可安裝的產品映像形式)。隨著應用程式的生成過程變得更加複雜,確保在每次生成期間都使用精確相同的生成步驟,同時實現儘可能多的自動化,以便及時產生一致的生產版本,這就變得更加重要。

Ant定義生成檔案之間的依賴關係,它它使用跨平臺的java類。使用Ant,能夠編寫單個生成檔案,這個生成檔案在任何java平臺上都是一致的操作(因為Ant本身也是使用java語言來實現的),這就是Ant最大的優勢。

Ant預設使用一個叫做build.xml的配置檔案。編寫一個最基本的build.xml

<?xml version="1.0" encoding="utf-8"?>
<project default="init">
	
	<target name="init">
		<mkdir dir="helloworld" />
	</target>
</project>


一個Ant的build.xml有一個根元素project,然後有很多目標<target>,mkdir是一個方法,建立目錄,如果這個build.xml存放在D盤下,我們在d:\下執行ant,就會在D盤下建立helloworld目錄,

D:\>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:
    [mkdir] Created dir: D:\helloworld

BUILD SUCCESSFUL
Total time: 1 second

修改mkdir dir=“helloworld\d\c\f”,再次執行,將直接建立d:\helloworld\d\c\f目錄,我們在最裡層的f中存放一個檔案,然後修改target

將mkdir去掉,改為

<delete dir="helloworld">

再次執行ant,將直接刪除helloworld及其子目錄。

我們也可以自己指定配置檔案,使用 -f選項:ant -f helloworld.xml

目標之間有時是有依賴關係的,這一點build.xml可以體現。

2、Ant生成檔案剖析

Ant沒有定義他自己的自定義語法;相反,它的生成檔案是用XM編寫的。存在一組Ant能夠理解的預定義XML元素,而且還可以定義新的元素來擴充套件Ant的功能。每個生成檔案由單個project元素組成,該元素又包含一個或多個target元素。一個目標(target)是生成過程中已定義的一個步驟,他執行任意數量的操作,比如編譯一組原始檔。並且這些操作本身是由其他專用任務標籤執行的。然後這些任務將根據需要被分組到各個target元素中。一次生成過程所必須的所有操作可以放入單個target元素中,但是那樣會降低靈活性。將那些操作劃分為邏輯生成步驟,每個步驟包含在他自己的target元素中,這樣通常更為可取。這樣可以執行整體生成過程的單獨部分,卻不一定要執行其他部分。

例如,通過僅呼叫某些目標,你可以編譯專案的原始碼,卻不必建立可以安裝的專案檔案。

如下,所有操作在一個target中:

<?xml version="1.0" encoding="utf-8"?>
<project default="init">
	
	<target name="init">
		<mkdir dir="helloworld" />
		<mkdir dir="hello" />
		<mkdir dir="world" />
		<mkdir dir="welcome" />
	</target>
</project>


執行結果:

D:\>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:
    [mkdir] Created dir: D:\helloworld
    [mkdir] Created dir: D:\hello
    [mkdir] Created dir: D:\world
    [mkdir] Created dir: D:\welcome

BUILD SUCCESSFUL
Total time: 0 seconds

多個target:

<?xml version="1.0" encoding="utf-8"?>
<project default="second">
	
	<target name="init">
		<mkdir dir="helloworld" />
		<mkdir dir="hello" />
		<mkdir dir="world" />
		<mkdir dir="welcome" />
	</target>
	<target name="second">
		<mkdir dir="abcd" />
		<mkdir dir="cde" />
		<mkdir dir="xyz" />
	</target>
</project>


注意:這裡project的default改為second,與第二個target的名字相同,指出預設執行哪一個target,執行結果:

D:\>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

second:
    [mkdir] Created dir: D:\abcd
    [mkdir] Created dir: D:\cde
    [mkdir] Created dir: D:\xyz

BUILD SUCCESSFUL
Total time: 0 seconds

只執行了target的name為second的目標。

<?xml version="1.0" encoding="utf-8"?>
<project default="second">
	
	<target name="init">
		<delete dir="helloworld" />
		<delete dir="hello" />
		<delete dir="world" />
		<delete dir="welcome" />
	</target>
	<target name="second" depends="init">
		<mkdir dir="abcd" />
		<mkdir dir="cde" />
		<mkdir dir="xyz" />
	</target>
</project>

修改second,增加depends=“init”,這一句的意思是這個target依賴名字為init的target,即要執行target為second,需要先執行名字name為init的target,執行結果:

D:\>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:
   [delete] Deleting directory D:\helloworld
   [delete] Deleting directory D:\hello
   [delete] Deleting directory D:\world
   [delete] Deleting directory D:\welcome

second:

BUILD SUCCESSFUL
Total time: 0 seconds

second沒有執行結果,因為目錄都存在不必執行了。
頂級project元素需要包含一個default屬性,如果在Ant被呼叫時沒有指定目標,這個屬性將指定要執行的目標。然後需要使用target元素來定義該目標本身。

對於上面的build.xml,我們可以單獨執行init:ant init

D:\>ant init
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:

BUILD SUCCESSFUL
Total time: 0 seconds

因為目錄都不存在,所以沒有任何操作,還可以一次指定多個目標,如:ant init second

D:\>ant init second
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:

init:

second:

BUILD SUCCESSFUL
Total time: 0 seconds

先執行init,再執行second,因為second依賴init,init再次執行

 ant生成檔案的基礎結構:

<?xml version="1.0"?>
<project default="init">
<target name="init"></target>
</project>

更進一步的:

<?xml version="1.0" ?>
<project default="init" name="Project">
<description>
A simple project 
</description>
<!-- XML comments can also be used -->
<target name="init" description="Initialize Argon database">
<!-- perform initializayion steps here -->
</target>
</project>


description標籤相當於一個註釋、說明,project、target標籤都有一個description屬性,用於對標籤進行說明和描述,當然也可以使用xml的註釋<!-- -->進行註釋。

可以看出,xml註釋可以使用在整個生成檔案中以提高清晰性。而且,Ant定義了它自己的description元素和description屬性,它們可用於提供更結構化的註釋。

Ant中的屬性類似程式語言中的變數,它們都具有名稱和值。然而與通常的變數不同,一經設定,Ant中的屬性就不可更改;它們是不可變的,就像java語言中的String物件。這起初看來似乎很有限制性,但這樣是為了遵循Ant的簡單原則:畢竟,他是一個生成工具,而不是一種程式語言。如果嘗試給某個現有屬性賦予一個新的值,這不會被看做是一個錯誤,但是該屬性仍然會保留其現有值。

定義與使用屬性

<property name="metal" value="beryllium" />

為了在生成檔案的其他部分引用這個屬性,使用以下語法:${metal}

例如,為了使用這樣一個值,它是另一個屬性的值的組成部分,將標籤寫成下面這樣:

<property name="metal-database" value="${metal}.db"/>

生成檔案的target是無序的,執行的先後主要看depends依賴關係。

location屬性:

屬性經常用於引用檔案系統上的檔案或目錄,但是對於使用不同路徑分隔符(例如,\與/)的平臺來說,這樣可能在跨越不同平臺時導致問題。Ant的location屬性專門設計用於以平臺無關的方式包含檔案系統路徑。像下面這樣使用location來代替value:

<property name="database-file" location="archive/database/${metal}.db" />

用於location屬性的路徑分隔符字元將被轉換為當前平臺的正確格式;而且由於檔名是相對的,它被認為是相對於專案的基目錄。我們同樣可以容易的寫為下面這樣:

<property name="database-file" location="archive\database\${metal}.db" />

這個標籤的兩個版本都會在不同的平臺具有相同的行為。

定義依賴關係:

生成一個專案一般需要許多步驟——例如首先要編譯原始碼,然後將它打包為java歸檔檔案(java Archive File,JAR)。這其中許多步驟都具有清楚定義的順序——例如,在編譯器從原始碼生成類檔案之前,你不能打包類檔案。與順序指定target所不同的是,Ant採用一種更靈活的方法來定義依賴關係。每個目標的定義依據的是在它能夠執行之前必須完成的其他所有目標。這是使用target元素的depends屬性來實現

依賴關係:

<target name="init"/>
<target name="preprocess" depends="init" />
<target name="compile" depends="init,preprocess"/>
<target name="package" depends="compile"/>

這裡如果執行target為package的目標,init只會執行一次,這與顯示在ant命令中指明init package不同。

這種方法允許你執行專案任何階段的生成過程;Ant會首先執行已定義的先決階段。在上面的例子中,如果讓Ant完成compile步驟,他將判斷出需要首先執行init和preprocess這兩個目標。init目標不依賴其他任何目標,因此他將首先被執行。然後Ant檢查preprocess target,發現它依賴init目標;由於已經執行了後者,Ant不會再次執行它,因而開始執行preprocess目標。最後可以執行compile任務本身。

注意目標出現在生成檔案中的順序並不重要:執行順序是由depends屬性唯一確定的。

將上面的目標寫到build.xml中,執行package目標,結果:

D:\>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
Buildfile: D:\build.xml

init:

preprocess:

compile:

package:

BUILD SUCCESSFUL
Total time: 0 seconds

3、在MyEclipse中建立build.xml,要注意生成檔案的存放位置,是在專案的根目錄下,例如建立了一個test專案,那麼build.xml就放在test專案目錄下,如果我們的專案目錄是d:\workspace\test\,則build.xml就在d:\workspace\test\下,而不是在src或其他目錄下。

建立build.xml後,其圖示應該變為一個螞蟻的樣子,如果沒有改變,修改myeclipse的preferences的General——Editors——File Associations,增加build.xml,關聯的editors選擇Ant Editor,並設為預設。

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" basedir="." default="package">
	
	<property name="hello" value="hello123"></property>
	<property name="world" value="world123"></property>
	
	<target name="init"></target>
	
	<target name="preprocess" depends="init">
	
		<mkdir dir="${hello}"/>
		<mkdir dir="${world}"/>
	</target>
	
	<target name="compile" depends="init,preprocess"></target>
	
	<target name="package" depends="compile"></target>
</project>

注意紅色部分,一般都是這樣寫,表示基目錄就是當前專案目錄。執行結果:

Buildfile: G:\workspace\test\build.xml
init:
preprocess:
    [mkdir] Created dir: G:\workspace\test\hello123
    [mkdir] Created dir: G:\workspace\test\world123
compile:
package:
BUILD SUCCESSFUL
Total time: 94 milliseconds

注意目錄,基目錄“.”現在代表的就是G:\workspace\test,也是專案的目錄。

myeclipse提供了一個ant檢視,方便除錯執行不同的目標。