保持領先
VMware 提供培訓和認證,助力您的職業發展。
瞭解更多近日來,我們注意到人們對由 OSGi bundle 組成的應用的構建解決方案的未來越來越感興趣。由於我們深度參與 OSGi,這件事情與我們息息相關,我們花費了大量時間研究客戶需求以及這些需求的解決方案。在這篇部落格文章中,我將概述我們已確定的需求,並提出我們認為能滿足這些需求的解決方案。
我非常期待聽到任何有額外需求、認為我們的需求是虛假的或有更好解決方案想法的人的意見。
當前 OSGi 構建的一個真正問題是依賴元資料可能在許多地方重複。對於 dm Server,我們在 ivy.xml、.classpath 和 MANIFEST.MF 檔案中都描述了依賴關係。OSGi 構建的任何長期解決方案都必須要求依賴元資料只有一個存放位置。
考慮到 OSGi 應用的獨特特性,嘗試從頭開始構建系統是很誘人的。我們曾經考慮過這個想法,但很明顯,這在技術上是不可行的,也不是為我們的使用者提供的最佳解決方案。
我們的使用者對其選擇的構建解決方案投入巨大,讓他們遷移似乎不符合實際。相反,使用者希望有一個能很好地融入他們現有 Maven 或 Ant 構建的解決方案。
遷移到 OSGi 的最簡單方法可能是開始從應用模組的相關元資料自動生成 manifest 檔案。理想情況下,這種方法將最大程度地減少對應用程式碼或開發人員處理程式碼方式的更改。
儘管生成 manifest 檔案是一種有效的方法,但許多使用者對將他們的 OSGi manifest 檔案視為依賴元資料的規範描述很感興趣。這些使用者希望從他們在 manifest 檔案中編寫的元資料來驅動構建。為了支援輕鬆建立 manifest 檔案,許多使用者希望看到對 manifest 模板的支援。manifest 模板允許自動生成樣板 manifest 內容,同時讓使用者能夠完全控制版本等重要資訊。
這種方法將 manifest 檔案用作 IDE 和離線構建中的中心依賴描述符。開發人員手動編寫 OSGi manifest 檔案,或藉助工具編寫,然後構建工具會使用該 manifest 檔案,其方式類似於 Maven 使用 pom.xml 和 Ivy 使用 ivy.xml。
使用 OSGi 元資料進行解析可以在構建期間應用完整的 OSGi 解析規則。這將使得構建時依賴解析與執行時發生的解析更加準確地匹配。
這種方法的一個潛在缺點是開發人員需要在他們的 manifest 檔案中指定測試依賴項。Maven 和 Ivy 都有標記僅用於測試環境的依賴項的方法,當使用 manifest 檔案進行依賴解析時,也需要類似的解決方案。
根據這些需求,我們推匯出了四種主要場景。有趣的是,每種場景都代表了我與 dm Server 經常互動的一個或多個使用者。
與下一個場景一樣,這是我們最常遇到的場景,也是我們目前投入最多時間研究的場景。採用這種方法時,開發人員進行開發任務的方式與他們處理任何普通 Maven/Eclipse 專案時一樣。
OSGi manifest 檔案由 Maven 和 Eclipse 的外掛生成。開發人員可以選擇讓 Eclipse 外掛作為增量構建的一部分或按需重新生成 manifest 檔案。
生成 OSGi manifest 所需的大部分元資料可以在 Java 程式碼(原始檔/位元組碼)中找到。然而,從位元組碼中無法推斷出合理的依賴版本號。在這種情況下,可以從 pom.xml 檔案或可自定義的 manifest 模板中提取版本。
manifest 模板可以承載除版本號以外的更多資訊,允許開發人員新增 OSGi 屬性和指令以及任何自定義頭部資訊。
這種方法類似於 Maven 的 pom 驅動方法,不同之處在於依賴元資料將從 ivy.xml 檔案中提取,而不是從 pom.xml 檔案中提取。
開發人員可以使用 Ant 任務在構建的適當階段執行 manifest 檔案生成。
這種方法最大的缺點是 Eclipse 中缺乏強大的 Ivy 整合。對於 Ivy 2,Eclipse 外掛的支援非常不足。我們正在考慮的一種方法是從生成的 manifest 檔案建立 Eclipse classpath。這是我們已經支援的工具,並將為接下來的兩個場景進行擴充套件。開發人員將編寫 ivy.xml 檔案,使用 Eclipse 外掛生成他們的 manifest 檔案,並讓 Eclipse classpath 自動更新。
在這種方法中,OSGi manifest 檔案是專案依賴元資料的最終宣告。開發人員可以選擇完全手動編寫 manifest 檔案,但更有可能的是他們會編寫一個 manifest 模板,然後讓我們的外掛完成其餘工作。
dm Server 工具已經包含了一個由 manifest 檔案驅動的 Eclipse classpath 容器,這將擴充套件以支援準確的傳遞性依賴解析。
為了支援此環境中的測試,外掛將允許同時編寫 MANIFEST.MF 和 TEST.MF 檔案,其中 TEST.MF 描述僅用於測試的依賴項,而 MANIFEST.MF 描述在測試和生產過程中都適用的依賴項。
對於此場景,最後剩下的一塊是如何接入 Maven。我們目前正在研究兩種方法:替換/整合 Maven 依賴解析器或生成 pom.xml 檔案。我很想聽聽您對哪種方法最有價值且對您最有益的看法。
這種方法與以 manifest 檔案驅動的方式使用 Maven 非常相似。與場景 2 不同,此場景不受 Ivy/Eclipse 整合不足的影響,因為我們將使用與場景 3 中相同的 manifest 檔案驅動的 Eclipse classpath 容器。
為了滿足上述要求,我們正在構建一套與 Maven、Ant 和 Ivy 協同工作的工具套件,為構建 OSGi 應用提供整合解決方案。
Bundlor 是我們內部使用了一段時間的工具,用於生成 OSGi manifest 檔案。我們主要用它來建立您在我們 企業 Bundle 倉庫 中看到的所有 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.internal 被暴露。使用 Import-Template 頭部資訊為所有匹配 org.springframework.* 模式的包名設定版本。專案程式碼被掃描以確定可能的匯入和匯出集合。然後使用模板檔案控制該集合中的哪些匯入/匯出實際進入 manifest 檔案以及它們的版本是什麼。重要的是,生成過程會為您正確生成 uses 元資料,這消除了最繁瑣的工作之一。
Bundlor 實際上會支援建立兩個 manifest 檔案:MANIFEST.MF 和 TEST.MF。TEST.MF 檔案將用於描述僅在測試期間需要的依賴項。這對於希望使用 manifest 驅動構建但不希望用測試依賴項汙染生產 manifest 檔案的開發人員來說非常重要。
在接下來的幾周,我們將釋出 Bundlor 的第一個公開里程碑版本。在此版本中,您將能夠在 Ant 和 Maven 中為專案生成 manifest 檔案,並能夠使用 manifest 模板自定義這些檔案。在之後的幾個里程碑版本中,我們將增加從 pom.xml 和 ivy.xml 檔案自動檢測依賴項版本的功能。
為了趕上 Bundlor 1.0 最終版,我們將把我們大部分示例中的手動編寫 manifest 檔案切換為使用 Bundlor 和 manifest 模板。此外,我們也將把 dm Server 遷移到 Bundlor,放棄所有手動編寫的 manifest 檔案。
BundlorEclipse 是一個 Eclipse 外掛,它讓 Bundlor 的功能直接在您的 Eclipse IDE 中可用。使用此外掛,您可以將完全增量的 manifest 檔案生成作為您正常 Eclipse 構建生命週期的一部分來執行。如果像我一樣,您在儲存按鈕上過於隨意,您可以將 BundlorEclipse 配置為僅在需要時才生成 manifest 檔案。
將其與即將釋出的 dm Server 容器內測試框架結合使用時,您將能夠啟動完整的 dm Server 測試環境,包括所有 bundle 的 manifest 檔案,這一切都可以在 Eclipse 中完成。
OSGi 有其自己的規則來解析模組之間的依賴關係以及如何驗證這些依賴關係並將其轉化為一致的類空間。在 OSGi 之外,構建工具工作在平面的 classpath 上,該 classpath 列出了要搜尋類的 JAR 包和目錄。
為了支援 manifest 驅動的構建,我們將建立一個離線依賴解析器,它無需啟動 Equinox 或 dm Server 即可執行 OSGi 解析。我們將把它與一個工具配對,該工具將把 OSGi 解析圖展平為用於編譯和測試的簡單 classpath。這個展平過程將完全由使用者配置,使用者將能夠提供策略資訊來管理 OSGi 圖中的多個版本如何對映到 classpath 中的單個版本。
使用依賴解析器,我們將能夠改進我們的 manifest classpath 容器,為每個 Eclipse 專案建立一個完整的、傳遞性的 classpath。
依賴解析器也將構成我們依賴解析器/pom.xml/ivy.xml 生成器工具的核心部分。這裡的關鍵觀察是,作為開發人員,您應該期望在 Eclipse 內部和構建工具中獲得一致的結果。
您可能知道,OSGi 技術總監 Peter Kriens 提供了一個名為 bnd 的工具,其用途與 Bundlor 類似。我們最初的立場是在我們自己的專案中使用 bnd,並將其作為我們工具的一部分。實際上,早在 Bundlor 出現之前,Spring Dynamic Modules 就已經使用 bnd 建立其 bundle 了。那麼,為什麼我們決定建立 Bundlor 呢?
建立 Bundlor 的主要原因是我們必須支援 bnd 中不存在的一些附加功能,例如:
這些功能用於支援 BundlorEclipse。我們在 Eclipse 中使用基於 JDT 的掃描代替位元組碼掃描,以改善使用者體驗,並更好地整合到 Eclipse 構建生命週期中。Eclipse 對部分正確的程式碼處理得很好,我們希望 Bundlor 也能以類似的方式支援部分程式碼。
在 BundlorEclipse 中,可以將 Bundlor 配置為在您每次在 IDE 中儲存更改時執行。為了提高效能,我們支援增量 manifest 檔案生成。當您更改程式碼時,Bundlor 可以跟蹤需要對 manifest 檔案進行的更改,並避免重新建立所有 manifest 檔案。
我們知道,儘管 Eclipse 是 Java 開發人員的主流 IDE,但仍有相當一部分開發人員使用 IntelliJ 和 NetBeans 等 IDE。
雖然我們不承諾親自為這些 IDE 構建任何外掛,但我們將把所有描述的工具開源,以便其他人可以為他們喜歡的 IDE 建立外掛。
我們構建工具的方法是儘量將盡可能多的功能封裝到通用庫中。我們致力於與 NetBeans 和 IntelliJ 團隊合作,幫助他們將我們的工具庫整合到他們的 IDE 中。
理想的最終結果是,無論您使用什麼 IDE,您仍然可以訪問相同的底層 OSGi 工具。
OSGi 構建的需求並不僅限於我概述的這 4 種場景。還有更多功能和增強功能可以改善開發人員使用 OSGi 應用的體驗。
許多公司會有大量非 OSGi bundle 的 JAR 檔案積壓。我們計劃擴充套件 Bundlor 以支援批次生成 bundle。在此模式下,您可以將 Bundlor 指向一個 JAR 檔案目錄,讓 Bundlor 為所有這些檔案建立 bundle,從而節省時間。此外,Bundlor 還能夠利用這些檔案之間的關係來確定依賴項的版本範圍應該是什麼。這將減少您必須編寫的模板程式碼量,同時仍然生成高質量的 bundle。
使用 manifest 驅動的構建方式構建 dm Server 應用時,您必須手動編寫初始的 manifest 匯入。透過支援倉庫驅動的程式碼補全,您將能夠在 Eclipse 中針對 dm Server 倉庫獲得程式碼補全,這將同時生成 Java 匯入和 manifest 匯入。使用此功能,您可以根據需要構建 manifest 依賴項,而無需切換到 manifest 檔案。