Java的Build工具—Ant應用指南(2)

Java的Build工具—Ant應用指南(2)

基本應用

建立工程的目錄

一般要根據工程的實際情況來建立工程的目錄結構。但是,有一些比較通用的組織形式可供參考,比如所有的jakarta項目都使用類似的目錄結構。下面讓我們來看一下這種目錄結構的特點。

表1

目錄 文件 bin 公共的二進制文件,以及運行腳本 build 臨時創建的文件,如類文件等 dist 目標輸出文件,如生成Jar文件等。 doc/javadocs 文檔。 lib 需要導出的Java包 src 源文件
對於一個簡單的工程,一般包括表1的幾個目錄。其中bin、lib、doc和src目錄需要在CVS的控制之下。當然在這樣的目錄結構上,也可以做一些調整,例如,可以建立一個extra目錄來放置需要發佈的Jar文件、Inf文件及圖像文件等。同樣,如果開發Web應用可以建立一個Web目錄放置JSP、HTML等文件。

如果我們開發的是一個比較複雜的項目,包括多個子項目,並且各個子項目是由不同的開發人員來完成的,那麼要如何來設計它的目錄結構?首先有一點是需要確定的,不同的子項目應該擁有不同的Build文件,並且整個項目也應該有一個總的Build文件。可以通過Ant任務或是AntCall任務調用子項目的Build文件,如下例:

<target name="core" depends="init">
<ant dir="components" target="core"/>
<ant dir="waf/src" target="core"/>
<ant dir="apps" target="core"/>
</target>

在各個子項目的耦合不是非常緊密的情況下,各個子項目應該有各自獨立的目錄結構,也就是說它們可以有自己的src、doc、build、dist等目錄及自己的build.xml文件,但是可以共享lib和bin目錄。而對於那些耦合緊密的子項目,則推薦使用同一個src目錄,但是不同的子項目有不同的子目錄,各個子項目的build.xml文件可以放在根目錄下,也可以移到各個子項目的目錄下。

編寫Build文件

要用好Ant工具,關鍵是要編寫一個build.xml文件。要編寫出一個結構良好、靈活可擴展的Build文件,有兩個問題要考慮,一是瞭解Build文件的基本結構,二是瞭解Ant定義的大量任務。

Ant的Build文件是一個標準的XML文件,它包含一個根節點Project,每個Project定義了至少一個或多個Target,每個Target又是一系列Task的集合。它們之間的關係如圖2所示。

20063816236340.gifscreen.width*0.7) {this.resized=true; this.width=screen.width*0.7;}">


圖2 build.xml文件的結構


每個Task是一段可被執行的代碼,比如,前例中的javac、jar就是兩個最常用的Task。Ant定義了大量的核心Task,我們要考慮的第二個問題正是如何去掌握這大量的Task。其實唯一的方法就是邊學習邊實踐,這方面最好的參考就是官方的Ant使用手冊。

外部文件的使用

使用外部的Property文件可以保存一些預設置的公共屬性變量。這些屬性可以在多個不同的Build文件中使用。

可以將一個外部的XML文件導入Build文件中,這樣多個項目的開發者可以通過引用來共享一些代碼,同樣,這也有助於Build文件的重用,示例代碼如下所示:

<!DOCTYPE project [
<!ENTITY share-variable SYSTEM "file:../share-variable.xml">
<!ENTITY build-share SYSTEM "file:../build-share.xml">
]>
<project name="main" default="complie" basedir=".">
&share-variable;
&build-share;
... ...

在J2EE項目中的應用

只要掌握了Ant的使用方法,在J2EE項目中的應用與在其它項目中的應用並沒有太大的不同,但是仍有幾點是需要注意的。

一是要清楚War和Jar文件的目錄結構,主要是War的配置文件web.xml文件的位置和EJB的配置文件(ejb-jar.xml和weblogic-ejb-jar.xml等)的位置,在調用Jar任務打包文件時一定要記得把它們也包含進來。一般在編譯之前就要注意把這些需打包的文件拷入相應目錄下。二是在J2EE項目中可能會涉及到一些特殊的任務,比如在Weblogic中會調用ejbc預編譯EJB的代碼存根,或者需要在Ant中同時發佈Jar到相應的服務器中等。可以用兩種途徑實現這些任務,一是擴展Ant任務實現這些任務,二是直接用Java任務來執行這些命令。下面是打包、發佈一個EJB的build.xml配置文件片斷,代碼如下:

<target name="deploy_HelloEJB" depends="compile">
<delete dir="${temp}/ejb_make"/> <!-- 首先刪除臨時目錄 -->
<delete file="${temp}/helloEJB.jar"/>
<!-- 刪除WebLogic域中老版本的EJB -->
<delete file="${weblogic.deploy.dest}/helloEJB.jar"/>
<!-- 創建META-INF目錄,放置ejb-jar.xml和weblogic-ejb-jar.xml -->
<mkdir dir="${temp}/ejb_make/META-INF"/>
<!-- 拷貝ejb-jar.xml和weblogic-ejb-jar.xml 到臨時目錄-->
<copy todir="${temp}/ejb_make/META-INF">
<fileset dir="etc/baseinfo">
<include name="*.xml"/>
</fileset>
</copy>
<!-- 拷貝所有的helloEJB類到臨時目錄 -->
<copy todir="${temp}/ejb_make/">
<fileset dir="${dest.classes}/"> <!-- dest.classes是輸出的類文件目錄 -->
<include name="${dest.classes}/helloEJB/**"/>
</fileset>
</copy>
<!-- 將所有這些文件打包成helloEJB.jar -->
<jar jarfile="${temp}/helloEJB.jar" basedir="${temp}/ejb_make"/>
<!-- 進行weblogic.ejbc編譯 -->
<java classpath="${wl_cp}" classname="weblogic.ejbc" fork="yes" >
<classpath>
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</classpath>
<arg value="${temp}/helloEJB.jar" />
<arg value="${temp}/helloEJB_deploy.jar" />
</java>
<!-- 拷貝/發佈到WebLogic的{DOMAIN}applications目錄 -->
<copy file="${temp}/helloEJB_deploy.jar" todir="${weblogic.deploy.dest}"/>
</target>

用Ant配合JUnit實現單元測試

Ant 提供了JUnit任務,可以執行單元測試代碼。如何使用JUnit,以及如何編寫測試用例(TestCase),感興趣的讀者可以參閱JUnit的相關文檔。在Ant中使用JUnit的方法非常簡單,首先需要把junit.jar拷入ANT_HOMElib下,確認在這個目錄下有optional.jar,因爲JUnit是Ant的擴展任務,需要引用這個擴展包。然後就是在Build文件中加入JUnit的任務,代碼如下:

<target name="run" depends="client">
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<classpath>
<pathelement location="client.jar" />
</classpath>
<formatter type="plain" />
<test name="com.sharetop.antdemo.HelloWorldTest" />
</junit>
</target>

高級話題

爲Ant開發擴展任務

爲Ant實現擴展任務其實是非常容易的,只需按照以下幾個步驟即可:

1. 創建一個Java類繼承org.apache.tools.ant.Task類;

2. 對每個屬性實現set方法。Ant會根據需要自動完成類型轉換;

3. 如果擴展的任務需要嵌套其它的Task,那麼這個Java類必需實現接口org.apache.tools.ant.TaskContainer;

4. 如果擴展的任務要支持Text,需要增加一個方法void addText(String);

5. 對每個嵌套的元素,實現create、add 或 addConfigured 方法;

6. 實現public void execute方法;

7. 在build.xml文件中使用 <taskdef> 來引用自定義的Task。

下面以一個簡單的例子來說明如何爲Ant增加一個hello任務,它可以連續打印多條信息,打印的次數由屬性count指定,而打印的內容則由它內嵌的一個helloinfo任務的message屬性指定,看上去這非常類似JSP中自定義標籤的一些概念,實現代碼如下:

//HelloInfoTask.java
package com.sharetop.antdemo;
import org.apache.tools.ant.*;
public class HelloInfoTask {
private String msg;
public void execute() throws BuildException {
System.out.println(msg);
}
public void setMessage(String msg) {
this.msg = msg;
}
}

下面是外部Task類的代碼:

//HelloTask.java
package com.sharetop.antdemo;
import org.apache.tools.ant.*;
public class HelloTask extends Task implements org.apache.tools.ant.TaskContainer
{
private Task info;
private int count;
public void execute() throws BuildException {
for(int i=0;i<count;i++)
info.execute();
}
public void setCount(int c){
this.count=c;
}
public void addTask(Task t){
this.info=t;
}
}

實現了這兩個Task,在build.xml文件中定義它的task name,就可以在Target中執行它了。如果你不想使用 <taskdef> 標籤來定義Task,也可以通過修改default.properties文件來實現引入新Task,這個文件位於org.apache.tools.ant.taskdefs 包裏。下例是一個使用 標籤來引入新Task的Build文件部分:

<target name="hello" depends="client">
<taskdef name="hello"
classname="com.sharetop.antdemo.HelloTask" classpath="client.jar"/>
<taskdef name="helloinfo"
classname="com.sharetop.antdemo.HelloInfoTask" classpath="client.jar"/>
<hello count="3" >
<helloinfo message="hello world" />
</hello>
</target> (未完待續)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章