轉自:http://www.ibm.com/developerworks/cn/java/j-ap05068/
讓開發自動化: 利用 Ivy 管理依賴項
使用公共存儲庫和 Apache Ant 共享其他項目的源代碼
級別: 初級
Paul Duvall ([email protected]), CTO, Stelligent Incorporated
2008 年 6 月 10 日
管理項目和工具之間的源代碼依賴項往往非常困難,但並不一定總是如此。在這一期“ 讓開發自動化 ”中,自動化專家 Parl Duvall 介紹瞭如何利用 Apache Ant 項目中的 Ivy 依賴項管理器來處理所有重要 Java 項目必須管理的無數依賴項。
實際上,所有軟 件開發項目都必須依靠來自其他項目的源代碼。例如,許多項目可能依靠 log4j 等日誌記錄工具和 Struts 之類的 Web 框架。您的開發團隊不會維護其他項目的源代碼,但要依靠其 API 來實現項目中的定製軟件。您的軟件所依靠的其他項目數量越多(包括這些項目自身的依賴項),構建軟件就變得越複雜。
|
我已經看到許多團隊使用各種不完善的技術,嘗試解決這種難題:
- 將全部有依賴關係的項目(JAR 文件)放在一個目錄中,此目錄將簽入項目的版本控制存儲庫。這種技術不必要地增加了存儲庫的大小,使得管理版本差異極爲困難。
- 將有依賴關係的 JAR 分配到一個公共文件服務器上,使團隊無法控制版本更改。
- 手動將 JAR 文件複製到各開發人員工作站上的指定位置。這種方法使得確定丟失的文件或修正版本極爲困難。
- 執行一條 HTTP
Get
命令,將文件下載到開發人員的工作站,手動執行或將其作爲自動構建的一部分。這種技術會造成未受管理的 JAR 文件。
我參加過一箇中型項目,包含 1,000 個 Java 類和 100 多個有依賴關係的 JAR 文件。(我們選擇了第一種不完美的技術:將所有 JAR 簽入項目的版本控制存儲庫。)圖 1 顯示了可能在此類項目中看到的一小部分依賴項的類型:
|
圖 1 表現出,Brewery 項目的源代碼依賴於 Hibernate、Struts 2、MySQL Connector 和 Cobertura。而 Cobertura 又依賴其他 JAR,如 asm-2.2.1.jar、jakarta-oro-2.0.8.jar 和 log4j-1.2.9.jar。此外,asm-2.2.1.jar 依賴 asm-tree-2.2.1.jar。這僅僅是可能出現的各類嵌套依賴項的一個簡單示例。即便是某個 JAR 的版本不正確,您也會體驗到難以排除的問題,例如編譯錯誤或意料之外的行爲。
Apache Maven 構建管理和項目管理工具已經吸引了 Java 開發人員的注意。Maven 引入了 JAR 文件公共存儲庫的概念,可通過公開的 Web 服務器訪問(稱爲 ibiblio)。Maven 的方法減少了 JAR 文件膨脹的情況,不會佔用大多數版本控制存儲庫。但使用 Maven 時,它會鼓勵您採用其 “慣例優於配置” 的方法來構建軟件,這會制約您定製構建腳本的靈活性。
如果您多 年來一直使用 Apache Ant,現在希望獲得使用公共存儲庫的優勢,又該如呢?您是否不得不接受 Maven 的構建方法來獲得這些收益?幸運的是,答案是否定的,這是由於一種稱爲 Apache Ivy 的工具 — Ant 的一個子項目。Ivy 提供了最一致、可重複、易於維護的方法,來管理項目的所有構建依賴項(在 參考資料 部分中可以找到 Maven 和 Ivy 的比較)。這篇文章介紹了安裝和配置 Ivy 來管理依賴項的基礎知識,指出了可參考的更多信息。
開 始使用 Ivy 非常簡單,只需創建兩個 Ivy 特有的文件,添加一些 Ant 目標即可。Ivy 特有的文件是 ivy.xml 和一個 Ivy 設置文件。ivy.xml 文件中列舉了項目的所有依賴項。ivysettings.xml 文件(可以隨意爲此文件命名)用於配置從中下載有依賴關係的 JAR 文件的存儲庫。
清單 1 展示了一個簡單的 Ant 腳本,它調用了兩個 Ivy 任務:ivy:settings
和 ivy:retrieve
。
<target name="init-ivy" depends="download-ivy"> |
在 清單 1 中,ivy:settings
定義了 Ivy 設置文件。對 ivy:retrieve
的調用從 ivy.xml 聲明的一個存儲庫中檢索 JAR 文件。
下 載並使用 Ivy 的方法有幾種。第一種是手動將 Ivy JAR 文件下載到 Ant lib 目錄中,也可下載到 Ant 腳本的類路徑中定義的某個目錄中。我迷上了自動化,所以更傾向於使用自動化替代方案:下載 Ivy 的 JAR 文件,在 Ant 目標中配置類路徑。清單 2 展示了這種技術的示例:
<?xml version="1.0" encoding="iso-8859-1"?> |
清單 2 中的第二行定義了 XML 名稱空間。antlib
在 ivy.jar 文件中引用 antlib.xml。其餘的 xmlns
指明瞭 ivy
Ant 任務的完全限定路徑。${user.home}/.ant
的 ivy.home
值是 ivy.jar 文件下載的目標位置。taskdef
定義了 ivy
Ant 任務,引用其類路徑的位置。download-ivy
目標下載 ivy-2.0.0-beta2.jar 並使用 dest
屬性爲其重命名。
一旦下載並配置了 Ivy,就可以使用任意 Ivy Ant 任務(如 清單 1 中調用的兩個任務)。
ivy.xml 文件是必不可少的,您在此文件中定義項目的全部有依賴關係的 JAR。清單 3 展示了一個示例:
<?xml version="1.0" encoding="ISO-8859-1"?> |
請注意,清單 3 未表示任何文件位置或 URL,允許您轉到其他目錄位置,而無需更改依賴項列表。info
元素中的 organisation
屬性標識了組織類型(如 .net、.org 或 .com)。後接 module
名稱。此模塊的依賴項列表遵循一種命名規範,在下一個清單中您將更清晰地看出此規範。目前,只需記住 dependency name="cobertura" rev="1.9"
將轉換爲 cobertura-1.9.jar 即可。
清單 4 是 Ivy 設置文件的示例。它定義了 清單 3 中 ivy.xml 文件所用的存儲庫位置和相關模式。
<ivysettings> |
清單 4 中的 filesystem
元素定義了本地工作站上的位置模式。兩個 url
元素定義了可用於下載 JAR 文件的多個位置:第一個元素定義了受我控制的 integratebutton.com
上的一個自定義存儲庫;第二個元素定義了包含大量開源 JAR 文件的外部 Maven 存儲庫(不受我控制)。如果 Ivy 無法從第一個存儲庫下載
— 比如此存儲庫宕機,或者文件未在指定位置 — 它將嘗試第二個位置。優點在於,一旦 Ivy 下載了一個
JAR,它就會將文件置入您的本地文件系統,不必再爲每一次構建重新下載這些文件。
|
一個模塊常常要依賴其他模塊。例如,在 圖 1
中可以看到,cobertura-1.9.jar 文件的多個依賴項中包括 asm-2.2.1.jar,而 asm-2.2.1.jar 又依賴於
asm-tree-2.2.1.jar。如果沒有像 Ivy 這樣的工具,您就需要確保類路徑中存在這些 JAR 的正確版本,保證 JAR
版本之間不存在衝突。而使用 Ivy,您只需定義 cobertura
模塊及其所有依賴模塊,如清單 5 中所示的 ivy.xml 文件那樣。切記,這個 ivy.xml 文件與 cobertura-1.9.jar 文件位於同一目錄。
<?xml version="1.0" encoding="UTF-8"?> |
清單 5 中特別強調的依賴項定義了 objectweb org
和名稱 asm
以及要使用的特定修訂版。Ivy 將此信息與 ivysettings.xml 文件中的存儲庫定義(如 清單 4 所示)一起使用,用於下載 JAR 文件的依賴項。
圖 2 展示了符合 清單 4 所示 ivysettings.xml 文件配置的存儲庫中的目錄結構:
請注意,圖 2 展示了一個 ivy.xml 文件(見清單 6),它定義了 asm
的依賴項。 在清單 6 中,針對 asm
模塊的 ivy.xml 文件片段表示了它惟一的依賴項 — asm-tree-2.2.1.jar:
... |
簡單說明一下,cobertura
模塊定義了三個依賴模塊:asm
、jakarta-oro
和 log4j
,如 清單 5 所示。而 asm
模塊又有一個依賴模塊,名爲 asm-tree
,如 清單 6 所示。
請注意,圖 3 中的 asm-tree
目錄結構與 圖 2 中的 asm
模塊結構相似:
當然,差別在於 JAR 文件包含不同的類,圖 2 所示的 ivy.xml 文件的定義描述了 asm-tree
模塊。(碰巧,asm-tree
模塊未在其 ivy.xml 文件中定義任何依賴項。)
|
既然您已經掌握了使用 Ivy 的基本知識,下面我將介紹其他一些有用的 Ant 任務。
Ivy 提供了一個任務,用於報告一個項目中的依賴文件。清單 7 展示瞭如何調用 Ivy 的 report
Ant 任務來創建依賴項列表:
<target name="ivy-report" depends="init-ivy"> |
清單 7 中的腳本生成了一份 HTML 報告,顯示了某項目的依賴文件列表。圖 4 展示了該報告:
還有其他許多針對 Ivy 的 Ant 任務可供您使用 — 通過爲 Maven 生成一個 POM 文件來清理本地文件系統緩存。表 1 顯示了部分 Ivy 的 Ant 任務及其用途:
Task | Purpose |
---|---|
settings
|
對於驗證包含存儲庫的主機最有用 |
cachepath
|
覆蓋本地文件系統上的默認緩存路徑,所下載的文件將存放在此路徑中 |
repreport
|
爲存儲庫中的幾個模塊生成報告 |
install
|
安裝一個模塊及其所有依賴項 |
makepom
|
通過 ivy.xml 文件創建一個 pom.xml file,供 Maven 使用 |
cleancache
|
清理本地文件系統緩存,強制在下一次構建時從存儲庫重新檢索 JAR 文件 |
參見 參考資料,瞭解 Ivy 中可用的其他 Ant 任務。
|
|
Ivy 集中管理依賴文件,消除了開發團隊將 JAR 文件從一個版本控制存儲庫複製到另一個存儲庫中時可能出現的膨脹現象。如果您正參與一個簡單的項目,將 JAR 文件簽入版本控制系統或使用本文開頭列出的其他某些技術可能不會顯著降低您的速度。但若您的項目規模越來越大,或者您在使用公共文件的企業環境中工作,一 種公共方法就變得十分必要。無論是哪種情況,Ivy 都能使定義項目依賴項更爲一致、更爲可行。因此值得您付出時間研究 Ivy 在您的項目中的應用。
學習
- 您可以參閱本文在 developerWorks 全球站點上的 英文原文 。
-
Apache Ivy:訪問 Ivy 項目網站,查看文檔、教程和社區資源。
- "Ivy in 4.2 steps" (Andrew Glover,testearly.com,2007 年 6 月):通過幾個簡單的步驟使 Ivy 開始運行。
-
Ivy / Maven2 Comparison(Apache Ant Ivy 項目):Ivy 與 Maven 2 依賴項管理之間的差異探討。
-
Ant in Action
(Steven Loughran 和 Erik Hatcher,Manning,2007年):這是一本出色的書籍,其中的第 11 章專門探討使用 Ivy 進行依賴項管理的內容。
-
讓開發自動化
(Paul Duvall,developerWorks):閱讀整個系列文章。
-
瀏覽 技術書店,查看關於上述和其他技術主題的書籍。
-
developerWorks Java 技術專區:數以百計的文章,介紹 Java 編程的所有方面。
獲得產品和技術