模組化是大型 Java 系統的關鍵特徵。建構腳本常將專案劃分為多模組以優化建構,但執行期模組劃分鮮少被考量。本系列第二篇聚焦靜態模組化:如何建立 Bundle、安裝至 OSGi 引擎、建立版本相依。下一篇將探討動態模組化。
Java 開發期以套件為模組單元,部署期以 JAR 為單元。Maven 等工具確保編譯期一致性,但執行期 Classpath 仍可能出現相依不一致。OSGi 解決方案:模組宣告相依需求,執行期啟動前先行檢查。OSGi R4.2 為當前規範版本。
OSGi 模組稱為 Bundle,本質為含額外資訊的 JAR 檔(MANIFEST.MF)。必要標頭:
Bundle-ManifestVersion: 2 (R4 規範)Bundle-SymbolicName:反向域名識別符,如 com.infoqBundle-Version:major.minor.micro.qualifier 格式最小化 Bundle 僅需上述三標頭。進階範例加入 Bundle-Activator(生命週期掛鉤,類似 main 方法)與 Import-Package(宣告執行期相依):
Bundle-Activator: com.infoq.ExampleActivator
Import-Package: org.osgi.framework
Bundle-Activator 指定啟動/停止時實例化並呼叫的類別;Import-Package 宣告程式碼所需套件,缺少將拋出 NoClassDefFoundError。
主流開源引擎:
| 引擎 | 授權 | 下載 | 啟動指令 | 常用 Shell 指令 |
|---|---|---|---|---|
| Equinox | EPL | org.eclipse.osgi_3.5.0.v20090520.jar | java -jar ... -console | install/start/stop/uninstall/ss |
| Felix | Apache License | bin/felix.jar | java -jar bin/felix.jar | install/start/stop/ps |
| Knopflerfish | BSD-like | framework.jar | java -jar framework.jar -xargs minimal.xargs | install/start/stop/bundles |
編譯打包:javac -cp framework.jar ... && jar cfm example.jar MANIFEST.MF com。安裝後引擎分配數值 ID,透過 ss 或 bundles 查詢。
模組化優勢:
public 僅限類別層級,OSGi 可精確控制匯出套件,未匯出套件對其他 Bundle 不可見。範例:com.infoq.templater Bundle 匯出 com.infoq.templater.api,隱藏 .internal 實作。Client Bundle 透過 Require-Bundle 或 Import-Package 相依,僅能存取 API,實作細節完全封裝,未來可安全替換實作。
# Templater Bundle MANIFEST
Export-Package: com.infoq.templater.api
# Client Bundle MANIFEST
Require-Bundle: com.infoq.templater
Import-Package: org.osgi.framework
Bundle 與套件均可版本化。Import-Package 或 Require-Bundle 可指定版本範圍:
Require-Bundle: com.infoq.templater;bundle-version="1.0.0"(最低 1.0.0)Import-Package: com.infoq.templater.api;version="[1.0,2.0)"(1.x 範圍,含 1.0 不含 2.0)OSGi 允許同一 Bundle 多版本共存(如舊客戶端用 1.0,新客戶端用 2.0),僅需確保單一 Bundle 傳遞鏈不同時相依衝突版本。
於 Equinox 中安裝 templater (ID 1) 與 amazon (ID 2),啟動 ID 2 輸出:Starting https://www.amazon.co.uk/dp/1411609255,驗證服務正常運作。
本文介紹 Equinox、Felix、Knopflerfish 三大引擎,實作帶相依關係的兩個 Bundle,闡述版本化相依機制。目前模組化仍為靜態,下一篇將探討 OSGi 動態特性:Bundle 如何響應其他 Bundle 的生命週期變化。