Maven 是一個(gè)軟件項目管理工具,它能夠管理一個(gè)項目生命周期中的構建、文檔、報告、發(fā)布等。Websphere ApplicationServer Community Edition (簡(jiǎn)稱(chēng)WASCE)是IBM發(fā)布的一款免費的開(kāi)源 J2EE 應用服務(wù)器。WASCE 構建在A(yíng)pache 社區開(kāi)發(fā)的 Geronimo 服務(wù)器的基礎之上,提供了更廣泛的硬件和軟件平臺的支持。在開(kāi)發(fā) J2EE項目時(shí),代碼的編譯、單元測試、文檔的生成以及把應用部署到 WASCE 是一個(gè)煩瑣而且需要反復進(jìn)行的過(guò)程。本文展示了使用 Maven來(lái)管理項目,自動(dòng)化項目的構建和到 WASCE 服務(wù)器的發(fā)布,提高項目的開(kāi)發(fā)效率。
Maven 是 Apache 開(kāi)源社區開(kāi)發(fā)的用于簡(jiǎn)化 Java 軟件項目構建的工具,它是在 Java項目構建領(lǐng)域的成熟理論和豐富經(jīng)驗的基礎之上,以高度重用的形式提供給開(kāi)發(fā)者。Maven的目標是要使得項目的構建更加容易,它把編譯、打包、測試、發(fā)布等開(kāi)發(fā)過(guò)程中的不同環(huán)節有機的串聯(lián)了起來(lái),并產(chǎn)生一致的、高質(zhì)量的項目信息,使得項目成員能夠及時(shí)地得到反饋。
在使用 Maven 的過(guò)程中,會(huì )經(jīng)常遇到以下概念,了解這些有助于更好的理解 Maven 的構建過(guò)程。
1. Project:Maven 把它所要構建的任何項目都稱(chēng)為一個(gè) Project。此 Project 應該符合下面定義的POM模型。一個(gè)Project 可以依賴(lài)于另一個(gè) Project;Project 還可以包含多個(gè)子 Project,子 Project 也是一個(gè)獨立的Project。Maven 可以管理 Project 之間的各種關(guān)系。
2. Project Object Model(POM):POM 定義了 Project 的元數據。Maven 可以根據這些元數據來(lái)構建這個(gè) Project。POM一般定義在 Project 根目錄下的 project.xml 文件中。
3. Dependency:一般的 Java 項目在編譯或運行時(shí)需要依賴(lài)于外部的包,在 Maven 中,這些包稱(chēng)為 Dependency。
4. Goal:Goal 是 Maven 中的執行單元,相當于 Ant 中的 task。每一個(gè) Goal都對應于項目構建過(guò)程中的一個(gè)操作,例如:Java 程序的編譯、web 應用打包。Maven 通過(guò) Plug-in的方式已經(jīng)提供了大多數需要經(jīng)常使用的 Goal,但對應特定的項目,也可以在 maven.xml 中定義自己的 Goal。
5. Plug-in:Maven 是通過(guò) Plug-in 來(lái)組織的。Maven 所提供的每一項功能都是通過(guò) Plug-in來(lái)完成的。Plug-in 是可以重用的,它定義了 Goal,并且使用在 POM 中定義的 Project 元數據來(lái)執行這些 Goal。
6. Repository:Repository 用來(lái)統一存放 Maven 在構建項目過(guò)程中所依賴(lài)的外部的包文件。有兩中類(lèi)型的Repository:Local Repository 和 Remote Repository。Maven 在構建過(guò)程中,會(huì )檢查 LocalRepository,如果沒(méi)有所依賴(lài)的包,會(huì )去檢查 Remote Repository,并且把此包自動(dòng)下載到 Local Repository。
第一次接觸 Maven 的開(kāi)發(fā)人員一般都存在困惑:我們已經(jīng)有 Ant 了,問(wèn)什么還需要 Maven?我們可以從一個(gè)項目的開(kāi)發(fā)、管理和構建過(guò)程來(lái)回答這個(gè)問(wèn)題。
下面假設我們有一個(gè)項目為 SampleApp1,首先我們使用 Ant 作為構建工具,需要進(jìn)行的工作如下:
1. 規劃 SampleApp1 項目,包括用來(lái)存放不同資源的目錄結果,需要使用的外部包文件等。
2. 編寫(xiě) build.xml。在 build.xml中,項目的定義信息(比如目錄信息和外部包依賴(lài)信息)和構建步驟混合在一起。這樣的一個(gè)顯著(zhù)缺點(diǎn)是對項目 SampleApp2,build.xml完全沒(méi)有可重用性。例如我們需要對一個(gè) web 應用打包,就需要在 build.xml 中進(jìn)行如下定義:
<target name="war" depends="init"> <war destfile="Filter.war" webxml="${filter}/WEB-INF/web.xml" compress="false"> <classes dir="${dest}"> <include name="**/*.*"/> </classes> <fileset dir="${filter}"> <include name="**/*.*"/> </fileset> </war> </target> |
3. 運行 Ant 構建項目。
下面我們再看使用 Maven 作為項目管理工具,需要進(jìn)行如下工作:
1. 運行如下命令來(lái)生成可以用 Maven 來(lái)管理的項目 SampleApp1:
maven genapp |
此命令生成了 SampleApp1 的原型,可以在此基礎上添加自己的資源。
2. 修改 project.xml。此文件只包含項目定義信息,比如目錄信息、外部包依賴(lài)、測試信息、報告等。Maven plug-in可以根據這些信息來(lái)構建項目。對于上面例子中對 web 應用打包的操作,在 Maven 中有一個(gè) plug-in可以完成此操作,我們不需要再重新定義,只需要調用如下命令:
maven war |
3. 運行 maven 構建項目。
從以上比較可以看出,主要的差別在第二步。Maven 通過(guò) POM,把項目元數據和項目構建過(guò)程定義分離開(kāi)來(lái),使項目構建過(guò)程定義可以得到充分重用??梢哉J為 Ant 是"拷貝-粘貼"形式的重用,而 Maven 是通過(guò) plug-in 方式實(shí)現了真正的重用。
除了重用性,Maven 還提供了其它特性,例如 Repository 機制,依賴(lài)管理等;而且還包含大量的可以重用的 Plug-in。
Geronimo 社區為了方便J2EE應用的開(kāi)發(fā)和部署,開(kāi)發(fā)了一套 Maven Plug-in,從而使得 Maven 可以用在基于Geronimo 的項目的整個(gè)構建過(guò)程中。WASCE 構建在 Geronimo 基礎之上,所以這套 Plug-in 也完全適用于 WASCE。
Geronimo 部署 Plug-in 可以啟動(dòng)和停止 WASCE 服務(wù)器、部署和卸載一個(gè)應用、啟動(dòng)和停止一個(gè)應用。
這個(gè) Plug-in 主要包含以下命令:

以上參數描述如下:
uri:用于連接到服務(wù)器的 URI。此 URI 采用如下形式:deployer:Geronimo:jmx://host:port。
username:連接到服務(wù)器的管理員的用戶(hù)名,默認情況下是 system。
password:連接到服務(wù)器的管理員的口令,默認情況下是 manager。
module:要部署的應用的文件路徑。
plan:要部署的應用的部署描述文件的路徑,此參數為可選項。
id:所部署的應用的 configId。
下面我們將通過(guò)一個(gè)例子 Arithmetic Example 來(lái)展示 Maven 在 WASCE 開(kāi)發(fā)中的應用。此例子的源程序在后面可以下載。
Arithmetic Example 是一個(gè)簡(jiǎn)單的計數器應用程序。為了只關(guān)注于 Maven 的使用,此應用只使用了 Servlet 和 JSP。此應用包括3個(gè)頁(yè)面
圖1是這些頁(yè)面之間的流程圖。

Maven 提供了一個(gè)名為 Genapp 的 Plug-in,它可以生成項目框架,簡(jiǎn)化項目的配置。運行此 Plug-in 時(shí),它會(huì )詢(xún)問(wèn)用戶(hù)一些信息,并且根據這些信息生成項目。主要詢(xún)問(wèn)的信息包括以下內容:
1. 要使用的項目模板。此 Plug-in 包括7種項目模板,經(jīng)常用的包括默認模板、web 應用模板、ejb 應用模板、struts 應用模板。Arithmetic Example 使用 web 應用模板。
2. 此應用的ID。此 ID 用來(lái)表示生成的包文件的名字。
3. 此應用的名字。此項目的一個(gè)簡(jiǎn)單描述。
4. 此應用的包名字。指定此應用最上層的包名字。Arithmetic Example 使用com.arithmetic.example。

Maven 還提供了一個(gè)名為 Eclipse 的 Plug-in,它可以把 Maven 項目生成 Eclipse 工程。這樣就可以利用 Eclipse 提供的強大的集成開(kāi)發(fā)環(huán)境來(lái)開(kāi)發(fā)我們的項目。

在生成 Eclipse 工程的過(guò)程中,可能需要從 Remote Repository 上下載一些本項目所依賴(lài)的包文件。
可以在 Eclipse 中把生成的工程導入進(jìn)來(lái),這時(shí)會(huì )發(fā)現有一些錯誤提示,這是因為生成的工程里用到了一個(gè) Classpath 變量MAVEN_REPO,此變量指向 Maven 在本地機器上的 Repository 目錄,在 windows 平臺,此變量的值一般為C:\Documents and Settings\Administrator\.maven\repository??梢酝ㄟ^(guò)arithexample 工程的屬性設置來(lái)添加此變量,如圖2所示。

設置完 MAVEN_REPO,就可以在 Eclipse 中編寫(xiě)所需要的 Servlet 和 JSP 了。
Arithmetic Example 的構建過(guò)程主要包括以下幾步:
1. 源程序的編譯。
2. 打包成 WAR 文件。
3. 部署到 WAS CE 服務(wù)器。
4. 啟動(dòng) Arithmetic Example 應用。
對應第一步和第二步,Maven 已經(jīng)提供了相應的 Goal。第三步和第四步,需要使用 Geronimo 部署 Plug-in提供的命令來(lái)編寫(xiě)自己的 Goal。對于特定于某一個(gè)項目的 Goal 需要定義在此項目根目錄下的 maven.xml 中,在 ArithmeticExample 的 maven.xml 中,我們定義了以下 Goal:
1. deploy:部署 Arithmetic Example 到 Geronimo 服務(wù)器。
2. start:?jiǎn)?dòng)部署的 Arithmetic Example 應用。
3. stop:停止部署的 Arithmetic Example 應用。
4. undeploy0:卸載部署的 Arithmetic Example 應用。
5. default:是一個(gè)默認 Goal,當運行 Maven 而不指定 Goal 時(shí),將會(huì )運行此 Goal。此 Goal 將會(huì )編譯源程序、打包應用成 WAR 文件、部署應用以及啟動(dòng)應用。
6. undeploy:此 Goal 停止 Arithmetic Example 應用,然后卸載此應用。
7. redeploy:此 Goal 先運行 undeploy,再運行 default。
<?xml version="1.0" encoding="UTF-8"?> <project default="default" xmlns:j="jelly:core" xmlns:u="jelly:util" xmlns:ant="jelly:ant" xmlns:velocity="jelly:velocity" xmlns:deploy="geronimo:deploy"> <goal name="default" prereqs="war,deploy,start"/> <goal name="undeploy" prereqs="stop,undeploy0"/> <goal name="redeploy" prereqs="undeploy,default"/> <preGoal name="java:compile"> <mkdir dir="${maven.build.dir}/xdoclet/webdoclet/WEB-INF" /> <attainGoal name="xdoclet:webdoclet" /> </preGoal> <goal name="deploy"> <deploy:distribute uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" module="${module.file}"/> </goal> <goal name="start"> <deploy:start uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> <goal name="stop"> <deploy:stop uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> <goal name="undeploy0"> <deploy:undeploy uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> </project> |
聯(lián)系客服