2008年7月30日 星期三

Ant 結合 XDoclet 部署 Web Application

推文
說明:
Ant 是純 Java 寫的建置工具,有點像 linux、unix 上的 make 工具,
XDoclet ,則是可以在你的 java code 裡的註解加一些以@為開頭的
meta data (attributes)屬性,而透過 XDoclet 引擎解析來產生一些 xml文
件,以達到自動部署及處理一些瑣碎的設定複製等等工作。

目的:
我們的目的就是使用 Ant 跟 XDoclet 來部署應用程式,在我的前一篇
使用 Eclipse BIRT 寫報表 (3) 的步驟 12~17 有提到的部署方式是用純
手動更改 web.xml 及複製一些檔案,但如果我每開發了一支 Servlet,每
次都要手動更改設定很不方便,於是我們就可以利用 Ant 跟 XDoclet
來達到自動部署及處理一些瑣碎事情的目的。

1. 下載 Ant 1.7.1
http://ant.apache.org/bindownload.cgi
apache-ant-1.7.1-bin.zip 目前版本為 1.7.1 版

下載 XDoclet 1.2.3
http://sourceforge.net/project/showfiles.php?group_id=31602
選 xdoclet 1.2.3 進入再點選 xdoclet-bin-1.2.3.zip

下載 Tomcat 6.0.16
http://tomcat.apache.org/download-60.cgi
選 Core zip 檔案為 apache-tomcat-6.0.16.zip

下載 JDK 6 Update 7
http://java.sun.com
選右邊 Popular Downloads: Java SE

2. 設定環境變數(我的環境變數如下)

JAVA_HOME = C:\jdk1.6.0_07 (注意最後不可加“\” )

將下載的 Ant 解壓縮即可
ANT_HOME = C:\JavaEclipse\ant_xdoclet\apache-ant-1.7.1 (注意最後不加“\”)

將下載的 Tomcat 6.0.16 解壓縮
CATALINA_HOME = C:\JavaEclipse\apache-tomcat-6.0.16

3. 準備的檔案有
a. Servlet 程式 HelloWorldServlet
b. build.xml,Ant 要建置用的檔案
c. build.properties,b 的屬性檔,一般用來設定相關的路徑

4. 將我們在這篇使用 Eclipse BIRT 寫報表 (3) 的步驟 1 所 download 的
birt-runtime-2_3_0.zip檔案解壓縮後,更改
birt-runtime-2_3_0\WebViewerExample\WEB-INF\web.xml 檔 案 名 稱 為
web-settings.xml,
將檔案內容的 tag,<?xml version="1.0"…?>及<web-app …>及</web-app>刪
掉,因為透過 XDoclet 合併檔案(web.xml)時,這些標簽 tag會重複,再來將
birt-runtime-2_3_0\WebViewerExample目錄底下的所有 檔案(包含目錄)複
製到 C:\JavaEclipse\antxdoclet\src\birt 目錄底下,而將我們更名的檔案
web-settings.xml 剪下複製到 C:\JavaEclipse\antxdoclet\src目錄底下。

5. 我會舉兩種方式部署,一種是透過 Eclipse,另一種是透過 Dos Command。

6. Eclipse 內建的 ant 工具為 1.7.0 版,ant 相關設定如下,預設的建置檔案名
稱為 build.xml,選 menu 的 WindowPreferences 畫面如下


7. 選 menu 的 ProjectProperties,點 XDoclet 按 Browse,將我們在步驟 1
下載的 xdoclet-bin-1.2.3.zip 檔案解壓縮後的目錄 xdoclet-1.2.3\lib 選進來,
Version 選 1.2.3 版,如下圖


按確定

8. 到我們要部署的 Servlet 程式 HelloWorldServlet,在程式裡的 import 底下的
Document 註解下 @web. 會 auto completion,因為已經結合了 XDocle,所
以會自動跳出小視窗讓你選屬性,如下圖


9. 我們將程式 import 底下的註解輸入如下,當然你還可以輸入其他屬性,在
彈出小視窗時參考,
/**
* @web.servlet name="HelloWorldServlet"
* display-name="HelloWorldServlet"
* @web.servlet-mapping url-pattern="/HelloWorldServlet"
*/
如下圖

第一、二行是部署到 Web Application 時會自動產生的 xml 語法寫入到
web.xml

<servlet>
<display-name>HelloWorldServlet</display-name>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>test.HelloWorldServlet</servlet-class>
</servlet>

第三行會產生相對應的
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorldServlet</url-pattern>
</servlet-mapping>


10. NewFile 如下圖

檔名為 build.xml (ant 預設建置的檔案名稱,當然你也可以在步驟 6 更改設定)
重複這步驟建立檔案名稱為 build.properties
build.xml 及 build.properties 的內容如底下 11 及 13 步驟

11. build.xml 檔裡的 build.properties 設定檔如下
tomcat.dir=C:/JavaEclipse/apache-tomcat-6.0.16
web.dir=C:/JavaEclipse/apache-tomcat-6.0.16/webapps
XDoclet.dir=C:/JavaEclipse/ant_xdoclet/xdoclet-1.2.3
workdir=C:/JavaEclipse/antxdoclet
javacode=C:/Documents and Settings/ted/workspace/HelloServlet
war.name=HelloServlet.war

說明:
第一行為 Tomcat Server 的目錄
第二行為部署 web 的目錄
第三行為我解壓縮檔案 xdoclet-bin-1.2.3.zip的目錄
第四行為工作目錄
第五行為 java source code 的目錄
第六行為部署的 war 檔名

12. build.xml 檔案內容說明如下
ant 語法解說如下

<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>

假設我們執行 target D,他會從 depends 屬性,先執行 A,再執行 B,
再執行 C。

所以我的 Project 的 default 屬性,執行 deploy 時,target 的順序為
clean->main。
標籤property file 為指定 build.xml 的設定檔 build.properties,與
build.xml 放在同一目錄下。

標籤property name 指定相關的路徑值。

標籤path id 設定相關 jar 的 classpath。

至於 target name="main" 的標籤底下,有一個 taskdef,這是ant 定義
可由其他 parse 解析器來定義相關 tag,我們這邊是用 XDoclet 所提
供的 webdoclet,相關詳細說明在apache-ant-1.7.1\docs 及
xdoclet-1.2.3\docs 都有說明。

在 web 標籤底下 deploymentdescriptor mergeDir="${src.dir}",即是我
們在步驟4 要合併的 web-settings.xml 檔,至於為何要這檔名,相關說
明在xdoclet-1.2.3\docs 進去選webdoclet 的deploymentdescriptor。
在 target name="deploy" 即是做一些java compile 及壓縮成 war 檔及
部署。

在 target name="clean" 主要作一些刪除及建立檔案目錄的工作。

13. build.xml 檔案內容如下
<?xml version="1.0"?>

<project default="deploy">

<echo message="部署 HelloServlet 及 BIRT Web Application"/>

<property file="build.properties"/>
<property name="javacode.dir" value="${javacode}/src"/>
<property name="src.dir" value="${workdir}/src"/>
<property name="des.dir" value="${workdir}/des"/>

<path id="webjar_path">
<fileset file="${tomcat.dir}/lib/*.jar"/>
</path>

<path id="XDocletjar_path">
<fileset file="${XDoclet.dir}/lib/*.jar"/>
<path refid="webjar_path"/>
</path>

<target name="main" depends="clean">
<taskdef name="web" classpathref="XDocletjar_path" classname= "xdoclet.modules.web.WebDocletTask"/>
<web destDir="${des.dir}/WEB-INF" force="${xdoclet.force}">
<deploymentdescriptor mergeDir="${src.dir}"/>

<fileset dir="${javacode.dir}" includes="**/*.java"/>
</web>
</target>

<target name="clean">
<echo message="刪除及建立des.dir目錄"/>

<delete dir="${des.dir}"/>
<delete file="${delTomcat.war}"/>
<mkdir dir="${des.dir}"/>
<mkdir dir="${des.dir}/WEB-INF"/>
<mkdir dir="${des.dir}/WEB-INF/classes"/>

<copy todir="${des.dir}" overwrite="true">
<fileset dir="${src.dir}/birt">
<include name="**/*"/>
</fileset>
</copy>
</target>

<target name="deploy" depends="main">
<javac srcdir="${src.dir}" destdir=
"${des.dir}/WEB-INF/classes">
<classpath refid="webjar_path"/>
</javac>
<jar destfile="${tomcat.dir}/webapps/${war.name}" basedir="${des.dir}"/>
</target>

</project>

14. 選 build.xml 按右鍵Run AsAnt Build 如下圖



15. 執行 Ant 成功後如下圖

16. 另一種方法執行 Dos Command,請確實執行步驟 2,因我們會用到環境變數,
切換到放 build.xml 的目錄,我的 build.xml剛在 Eclipse Workspace 的
HelloServlet project 目錄下建立的,下指令
cd C:\Documents and Settings\ted\workspace\HelloServlet,如下圖
ant –buildfile 檔名(一般預設為 build.xml),或直接下 ant 即可,
或要知道更多參數,ant --help

17. 啟動 C:\JavaEclipse\apache-tomcat-6.0.16\bin\startup.bat,
(因我裝了兩個 Tomcat Server,所以另一個用 dos command run startup.bat)
在瀏覽器數入網址 http://localhost:8080/HelloServlet/HelloWorldServlet
即可看到我們寫的 HelloWorldServlet 及 BIRT 部署成功


http://localhost:8080/HelloServlet/frameset?__report=test.rptdesign&sample=my+par
ameter


18. 當然我們開發第二支第三支…等等 Servlet 程式,就可重複步驟 9 在輸入相
關@doc tag 即可,開發 jsp 程式也是類似方式,相關 tag 可參考 doc,然
後要部署到 Web Application 只要執行 ant 就完成編譯及部署是不是很方
便,雖然 XDoclet 在 1.2.3 版就沒在更新了,支援到 servlet api 2.4,可以由
它的 deploymentdescriptor 的屬性 servletspec Valid values: 2.2, 2.3, 2.4 值可
知,但仍然可用於 servlet api 2.5(Tomcat6),只是可能某些功能無法使用,
但依然非常好用。