我們建構 OSGi 應用程式的計畫

工程 | Rob Harrop | 2009 年 3 月 18 日 | ...

最近幾天和幾週,我們看到越來越多人對組成 OSGi 綁定 (bundle) 應用程式的建構解決方案的未來感興趣。由於我們大量參與 OSGi,這對我們來說非常重要,我們花了很多時間研究客戶需求和這些需求的解決方案。在這篇部落格文章中,我將概述我們已確認的需求,並提出我們認為可滿足這些需求的解決方案。

我非常有興趣聽到任何有額外需求的人的意見,或者認為我們的需求是假的,或者對解決方案有更好的想法。

OSGi 建構的需求

不重複相依性元數據

目前 OSGi 建構的一個實際問題是,相依性元數據可能會在多個地方重複。對於 dm Server,我們在 ivy.xml、.classpath 和 MANIFEST.MF 檔案中描述了相依性。任何 OSGi 建構的長期解決方案都必須只需要一個相依性元數據位置。

與現有的建構解決方案配合使用

鑑於 OSGi 應用程式的獨特性質,很想嘗試從頭開始使用建構系統。我們一度考慮過這個想法,但後來發現這在技術上不可行,也不是我們使用者的最佳解決方案。

我們的使用者在他們選擇的建構解決方案中投入了大量資金,讓他們遷移似乎不是務實的方法。相反地,使用者想要一個可以順利整合到他們的 Maven 或 Ant 建構中的解決方案。

自動產生 manifest 檔案

遷移到 OSGi 最簡單的方法可能是開始根據應用程式模組的相關元數據自動產生 manifest 檔案。理想情況下,這種方法將導致應用程式程式碼或開發人員使用該程式碼的方式發生最小的變更。

從 OSGi manifest 衍生建構相依性

雖然 manifest 產生是一種有效的方法,但許多使用者對將他們的 OSGi manifest 視為相依性元數據的規範描述感興趣。這些使用者希望從他們在 manifest 中編寫的元數據中驅動他們的建構。為了支援輕鬆建立 manifest,許多使用者希望看到對 manifest 範本的支援。manifest 範本允許自動產生樣板 manifest 內容,同時讓使用者可以完全控制版本等重要資訊。

這種方法使用 manifest 作為 IDE 和離線建構中的中央相依性描述符。開發人員手動編寫 OSGi manifest,或借助工具,建構工具以類似於 Maven 使用 pom.xml 和 Ivy 使用 ivy.xml 的方式使用 manifest。

使用 OSGi 元數據進行解析,允許在建構期間套用整套 OSGi 解析規則。這將允許更準確地匹配建構時相依性解析和運行時將發生的解析。

這種方法的潛在缺點是開發人員需要在他們的 manifest 中指定測試相依性。Maven 和 Ivy 都有標記僅在測試環境中使用的相依性的方法,並且在使用 manifest 進行相依性解析時也需要類似的解決方案。

情境

根據這些需求,我們得出了四個主要情境。有趣的是,每個情境都由我經常與 dm Server 互動的一個或多個使用者代表。

1. Maven 和 Eclipse - pom.xml 驅動

與下一個情境一樣,這是我們最常遇到的情況,也是我們目前花費最多時間處理的情況。透過這種方法,開發人員正在執行他們的開發任務,就像他們對待任何正常的 Maven/Eclipse 專案一樣。

OSGi manifest 檔案由 Maven 和 Eclipse 的外掛程式產生。開發人員可以選擇讓 Eclipse 外掛程式在增量建構或隨選時重新產生 manifest。

產生 OSGi manifest 所需的大部分元數據都可以在 Java 程式碼(原始碼/位元組碼)中找到。但是,不可能從位元組碼中衍生出合理的相依性版本號碼。在這種情況下,可以從 pom.xml 檔案或從可自訂的 manifest 範本中提取版本。

manifest 範本可以攜帶比版本號碼更多的資訊,允許開發人員新增 OSGi 屬性和指令以及任何自訂標頭。

2. Ant、Ivy 和 Eclipse - ivy.xml 驅動

這種方法與 Maven、pom 驅動的方法類似,不同之處在於相依性元數據將從 ivy.xml 檔案中提取,而不是從 pom.xml 檔案中提取。

開發人員將可以使用 Ant 任務在建構的適當階段執行 manifest 產生。

這種方法的最大缺點是 Eclipse 中缺乏引人注目的 Ivy 整合。對於 Ivy 2,Eclipse 外掛程式支援非常缺乏。我們正在考慮的一種方法是從產生的 manifest 建立 Eclipse 類別路徑。這是我們已經支援的工具,並且將擴展到下兩個情境。開發人員將編寫 ivy.xml 檔案,使用 Eclipse 外掛程式產生他們的 manifest,並自動更新 Eclipse 類別路徑。

3. Maven 和 Eclipse - MANIFEST.MF 驅動

在這種方法中,OSGi manifest 檔案是專案相依性元數據的明確宣告。開發人員可能會選擇手動編寫整個 manifest,但他們很可能會編寫 manifest 範本並讓我們的外掛程式完成剩下的工作。

dm Server 工具已經帶有一個由 manifest 驅動的 Eclipse 類別路徑容器,這將擴展到支援準確的傳遞相依性解析。

為了支援在此環境中進行測試,這些外掛程式將允許編寫 MANIFEST.MF 和 TEST.MF 檔案,其中 TEST.MF 描述僅適用於測試的相依性,而 MANIFEST.MF 描述在測試和生產期間都適用的相依性。

此情境的最後一塊是如何插入 Maven。我們目前正在研究兩種方法:取代/整合 Maven 相依性解析器或產生 pom.xml 檔案。我很想聽聽您對哪種方法最有價值並且對您最有益的看法。

4. Ant、Ivy 和 Eclipse - MANIFEST.MF 驅動

這種方法與以 manifest 驅動的方式使用 Maven 非常相似。與情境 2 不同,此情境不會受到缺乏良好的 Ivy/Eclipse 整合的影響,因為我們將使用與情境 3 中相同的 manifest 驅動的 Eclipse 類別路徑容器。

OSGi 建構的工具

為了滿足概述的需求,我們正在建構一套與 Maven、Ant 和 Ivy 一起運作的工具,以提供建構 OSGi 應用程式的整合解決方案。

Bundlor

Bundlor 是我們內部使用了一段時間的工具,用於產生 OSGi manifest。我們主要使用它來建立您在我們的 Enterprise Bundle Repository 中看到的所有綁定 (bundle)。Bundlor 可用於為那些在建立時沒有考慮到 OSGi 的舊版程式庫產生 manifest。Bundlor 也可用於為您專門針對 OSGi 建立的綁定 (bundle) 產生 manifest。Bundlor 消除了建立高品質綁定 (bundle) manifest 的大部分繁瑣工作。

Bundlor 支援 manifest 範本的概念,該範本允許您自訂產生的 manifest。使用範本,您可以將版本和屬性新增至套件匯入和匯出、將套件從匯出中排除、在自動偵測不可能時新增匯入,以及新增額外的 manifest 標頭。下面的程式碼片段顯示了我們的一個範例應用程式中的 manifest。

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: GreenPages Service
Bundle-SymbolicName: greenpages
Bundle-Vendor: SpringSource Inc.
Bundle-Version: 1.0
Import-Template: org.springframework.*;version="[2.5.6.A,3.0)"
Excluded-Exports: greenpages.internal

在這個範例中,Excluded-Exports 標頭用於防止公開 greenpages.internalImport-Template 標頭用於為所有符合 org.springframework.* 模式的套件名稱設定版本。掃描專案程式碼以確定可能的匯入和匯出集合。然後使用範本檔案來控制此集合中的哪些匯入/匯出實際上進入 manifest 以及它們具有哪些版本。重要的是,產生過程將正確地為您產生 uses 元數據,從而消除最繁瑣的工作之一。

Bundlor 實際上將支援建立兩個 manifest 檔案:MANIFEST.MF 和 TEST.MF。TEST.MF 檔案將用於描述僅在測試期間需要的相依性。這對於想要使用 manifest 驅動建構但不希望用測試相依性污染生產 manifest 的開發人員來說很重要。

在接下來的幾週內,我們將發布我們的第一個 Bundlor 公開里程碑。在此版本中,您將能夠從 Ant 和 Maven 中為專案產生 manifest,並且您可以使用 manifest 範本自訂這些 manifest。在之後的幾個里程碑中,我們將新增從 pom.xml 和 ivy.xml 檔案自動偵測相依性版本的支援。

我們將切換我們的大部分範例,從手寫 manifest 轉為使用 Bundlor 和 manifest 範本,以便及時推出 Bundlor 1.0 最終版。此外,我們也將把 dm Server 遷移到 Bundlor,丟棄我們所有手寫的 manifest。

BundlorEclipse

BundlorEclipse 是一個 Eclipse 外掛程式,可讓 Bundlor 功能直接在您的 Eclipse IDE 中使用。使用此外掛程式,您可以讓完全增量的 manifest 產生作為您正常 Eclipse 建構生命週期的一部分來執行。如果您像我一樣,在使用儲存按鈕時有點太自由和容易,您可以將 BundlorEclipse 配置為僅在隨選時產生 manifest。

將其與即將推出的 dm Server 容器內測試框架結合使用時,您將能夠啟動完整的 dm Server 測試環境,其中包含所有綁定 (bundle) 的 manifest 檔案,所有這些都來自 Eclipse 內部。

離線相依性解析器

OSGi 有其自己的規則,用於解決模組之間的相依性,以及如何驗證這些相依性並將其轉換為一致的類別空間。在 OSGi 之外,建構工具在平面類別路徑上運作,該路徑列出了用於搜尋類別的 JAR 和目錄。

為了支援 manifest 驅動的建構,我們將建立一個離線相依性解析器,該解析器在不啟動 Equinox 或 dm Server 的情況下執行 OSGi 解析。我們將把此工具與一個工具配對,該工具會將 OSGi 解析圖壓平為一個簡單的類別路徑,用於編譯和測試。此壓平過程將完全由使用者配置,使用者將能夠提供原則資訊,以控制如何將 OSGi 圖中的多個版本對應到類別路徑中的單一版本。

Manifest 類別路徑容器

使用相依性解析器,我們將能夠改進我們的 manifest 類別路徑容器,以為每個 Eclipse 專案建立完整的傳遞類別路徑。

Maven/Ivy 相依性解析器/pom.xml/ivy.xml 產生器

這個相依性解析器也將成為我們的相依性解析器/pom.xml/ivy.xml產生器工具的核心部分。這裡的關鍵觀察是,作為開發人員,您應該期望在 Eclipse 內部以及您的建置工具中獲得一致的結果。

為什麼選擇 Bundlor 而不是 Bnd?

您可能已經知道,OSGi 技術總監 Peter Kriens 提供了一個名為 bnd 的工具,其用途與 Bundlor 類似。我們最初的立場是為我們自己的專案使用 bnd,並將其作為我們工具的一部分。事實上,在 Bundlor 出現之前,Spring Dynamic Modules 已經使用 bnd 來建立其 bundles。那麼,我們為什麼決定創建 Bundlor 呢?

創建 Bundlor 的主要原因是我們必須支援一些 bnd 中沒有的額外功能,例如:

  • 基於 JDT 的原始碼掃描
  • 部分程式碼處理
  • 增量式 manifest 建立

這些功能用於支援 BundlorEclipse。我們在 Eclipse 中使用基於 JDT 的掃描來代替位元組碼掃描,以改善使用者體驗,並更好地整合到 Eclipse 建置生命週期中。 Eclipse 能夠很好地處理部分正確的程式碼,我們希望 Bundlor 能夠以大致相同的方式支援部分程式碼。

在 BundlorEclipse 中,可以設定 Bundlor 在每次儲存 IDE 中的變更時執行。為了提高效能,我們支援增量式 manifest 產生。當您對程式碼進行變更時,Bundlor 可以追蹤必須對 manifest 檔案進行哪些變更,並避免重新建立所有 manifest。

使用 Eclipse 以外的 IDE

我們知道,雖然 Eclipse 是 Java 開發人員的主要 IDE,但仍有相當多的開發人員使用 IntelliJ 和 NetBeans 等 IDE。

雖然我們不會承諾為這些 IDE 建置任何插件,但我們將提供所有描述的工具作為開放原始碼,使其他人能夠為他們喜歡的 IDE 創建插件。

我們建置工具的方法是盡可能將更多功能封裝到通用程式庫中。我們致力於與 NetBeans 和 IntelliJ 團隊合作,以幫助他們將我們的工具程式庫整合到他們的 IDE 中。

理想的最終結果是,無論您使用哪種 IDE,您仍然可以存取相同的底層 OSGi 工具。

進一步的需求

OSGi 建置的需求並不止於我概述的四個情境。還有許多其他功能和增強功能可以改善開發人員使用 OSGi 應用程式的體驗。

批量 bundle 產生

許多商店會積壓大量非 OSGi bundles 的 JAR artifacts。我們計畫擴展 Bundlor 以支援批量 bundle 產生。在這種模式下,您可以將 Bundlor 指向一個 JAR 目錄,並讓 Bundlor 為所有這些 JAR 創建 bundles,從而節省時間。此外,Bundlor 將能夠使用這些 artifacts 之間的關係來計算依賴項的版本範圍。這將減少您必須編寫的樣板程式碼量,同時仍然產生高品質的 bundles。

Repository 驅動的程式碼完成

當使用 manifest 驅動的建置來建置 dm Server 應用程式時,您必須手動編寫初始 manifest 匯入。透過對 Repository 驅動的程式碼完成的支援,您將能夠針對 dm Server repository 獲得 Eclipse 程式碼完成,這將產生 Java 匯入和 manifest 匯入。使用此功能,您將能夠根據需要建立 manifest 依賴項,而無需切換到 manifest 檔案。

取得 Spring 電子報

隨時關注 Spring 電子報

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部