2005年9月5日

Maven 的類別庫相依性管理機制

玩了兩天 Maven 1.x 後,有些話不吐不快…

對於散佈套件的態度

個人很在意每一個確定要散佈的套件必須包含重新散佈時所需的完整設定資訊,甚至最好將 IDE 工具的設定一起包進去更好。這樣的做法可以當成是一種原始檔備份作業,只需從正式環境中下載該散佈包後即可進行修正並重新發佈。

使用 Ant 進行應用系統部署的原因

先前會使用 Ant 做專案部署工具的主因在於一個人性的重大弱點:懶;而另一方面則是為了避免人為失誤所導致的錯誤部署動作。當專案愈來愈多時卻發現一個問題:每一個專案會包含自己的相依性類別庫。

每個專案各玩各的好處是避免相互干擾,但壞處呢?

  1. 同一個 jar 檔分別存放在許多專案目錄下。
  2. 各專案間對同一個 jar 類別庫卻可能混有多種版本,造成維護上的困擾。

使用 Maven 管理專案的目的

就因為 Ant 必須自行管理相依性類別庫的關係,所以在看過 跑吧!電腦 (Run!PC) 對 Maven 的說明後即覺得這是一個可以解套的新工具。換句話說,當我必須將專案移交給他人時,不必再告訴交接者必須注意類別庫各版號間有無不同,更不必在一個散佈套件包中註解(在 jar 檔中)或附加(在 war 檔內)該專案必須使用的所有類別庫資訊。

實情是?

不過現實總難盡如人意,我發現只要某一個類別庫有特別的 License 限制時,我們將無法從公開的資源庫中下載到指定的 jar 檔,如 javamail 及 jndi 各 interface 等等。

有人會說這可以透過自訂 Maven Local Repository 本地資源庫來解決,但個人認為這是未考慮到交接者不一定熟悉 Java 各項設定的自私想法,換句話說這無法滿足個人對散佈套件的要求。

怎麼辦?

我是想過可不可以將這些無法提交到公開資源庫的類別庫套件包放到專案目錄下,然後在建置過程中去檢查相關的類別庫是否已提交到 Local Repository 以決定是否先執行自動提交程序。

可惜的是 Maven 會先進行相依性處置,只要找不到指定的類別庫後隨即自行結束建置動作,換句話說這個自動提交程序還沒開始前,Maven 就不玩了…

Maven 也可重新指定建置描述檔的名稱,這個方式可以避開前述的相依性檢查的問題。 但是我還是找不到在 Maven 中讀入類別庫目錄清單以及如何比對檔案是否存在的方法,這讓我開始考慮是否要將所有專案全數移轉到 Maven 上,也許過一段時間後再看看好了。

找到如何讀入檔案清單的方法了 - 使用 fileScanner:

讀入指定目錄下之檔案清單
    <ant:fileScanner var="jarFileList">
      <ant:fileset dir="${basedir}/resources/libs">
        <ant:include name="**/*.jar" />
      </ant:fileset>
    </ant:fileScanner>
    <j:forEach var="jarFile" items="${jarFileList.iterator()}" trim="yes">
      <ant:echo>
            ${jarFile}
      </ant:echo>
    </j:forEach>

是否每一個應用系統都要提供自動提交類別庫到本地資源庫的功能?

不!一般公司的應用系統開發只會相依於某些公司自行發展的套件庫,只要這些套件庫提供自動提交的程序即可,其他應用系統會在檢查不到這些專屬套件庫時即建置失敗。當發生此問題時只要執行所需套件庫的 deploy 動作即可!

其他替代方案?

雖然說或許可以透過自訂資源庫位置使得專案所需的類別庫可以跟著散佈包一起走,但這又回到了 Ant 所碰到的問題:每一個專案都得揹著數個大家都有的類別庫檔案,那麼看起來,Maven 似乎並未真正解決 Ant 令人詬病的問題?