Eclipse IDE 與 Eclipse Rich Client Platform (RCP) 的核心架構,均建立在 Open Services Gateway Initiative (OSGi) 規格的實作之上。本文將從插件的定義出發,追溯 Eclipse 從 2.1 版本專屬插件機制演進至現今基於 OSGi 標準的歷程,並詳細解析 manifest.mf 中的關鍵配置選項,幫助開發者徹底掌握兩者的協作模式。
根據 Eclipse 線上幫助定義,插件是「為系統提供功能的代碼和/或數據的結構化包」。這些功能可以是擁有公共 API 的 Java 類庫、平台擴展,甚至是文檔。關鍵在於「結構化」:所有插件遵循統一的結構定義,無論提供的是日誌服務還是 UI 編輯器,皆以相同方式被識別與管理。
早期 Eclipse 版本雖然也是插件集合,但依賴自研的插件系統管理交互。隨著 IDE 功能增長,動態安裝/停用插件、生命周期管理等需求促使 Eclipse 團隊決定採用 OSGi R4 規格替換原有框架。OSGi 本質是一個基於 Java 的組件與服務模型,核心單位是「Bundle(綁定包)」。在 Eclipse 語境下,插件與 Bundle 可視為同義詞。
OSGi 通過專用類加載器強制執行模組化邊界:一般 Java 應用中 CLASSPATH 所有類互相可見,而 OSGi 僅允許根據 manifest.mf 聲明的導出/導入包進行交互。Eclipse 採用了 OSGi 的模組化與生命周期子集,但保留了自家的「擴展點」機制作為組件間協作的主要方式,而非依賴 OSGi 服務註冊表。
Eclipse 3.0 時代,plugin.xml 一次性包含依賴關係、運行時庫、擴展點與擴展定義。以 org.eclipse.pde.ui 為例,其 <runtime> 聲明導出所有包,<requires> 列出數十個依賴插件。
自 Eclipse 3.1 起,依賴管理移至標準化的 META-INF/MANIFEST.MF,plugin.xml 專注於擴展點與擴展的 XML 定義。對比可見:
plugin id 作為唯一標識<import plugin=.../><export name="*"/> 通配符這一變更雖引發社區爭議(失去通配符便利),但帶來顯著性能提升:框架無需掃描每個 JAR 確定類內容;同時強制開發者明確設計公共 API,內部實現自動封裝,避免意外依賴。
| 屬性 | 說明 |
|---|---|
| Bundle-Activator | 啟動/停止 Bundle 的類,需實作 BundleActivator 接口 |
| Bundle-ClassPath | Bundle 內部類路徑,可包含 JAR 或目錄,「.」代表根目錄 |
| Bundle-Version | 版本號,支援導入/導出時的版本範圍控制 |
| Export-Package | 顯式聲明對外可見的包,支援 x-internal、x-friends 等 Eclipse 擴展屬性 |
| Import-Package | 顯式聲明所需外部包,優先於 Require-Bundle 解析,可標記 resolution:=optional |
| Require-Bundle | 聲明依賴整個 Bundle 及其導出包,解析順序在 Import-Package 之後 |
為滿足平台需求,Eclipse 在 OSGi 基礎上增加:
osgi.resolver=strict 使用,前者標記內部包禁止外部引用,後者白名單允許特定 Bundle 訪問true 時啟動階段即載入 Bundle,支援例外類列表osgi.os、osgi.arch 等屬性進行條件啟動Eclipse Equinox 已成為 OSGi 參考實作,並主導 JSR 291 推動規格演進。從伺服器端 Servlet 整合到動態組件管理,Eclipse/OSGi 生態持續拓展邊界,為模組化企業級應用奠定堅實基石。
