過去數年,模組化始終是 Java 演進的核心議題。從已廢止的 JSR 277、OSGi 標準化的 JSR 291,到 JDK 內部模組化專案 Jigsaw(JSR 294),模組化已成 Java 生態必經之路。本文系統梳理模組化核心觀念、編譯/執行時差異、依賴地獄成因,並盤點 OSGi、Jigsaw 等主流方案現狀。
模組化將系統拆解為獨立開發、透過標準介面通訊的單元,本質是「關注點分離」的大尺度實踐。Java 語言本身未內建模組系統(僅有 package),但實際上每個類庫(Log4j、Hibernate、Tomcat)皆是事實上的模組。問題在於:傳統 classpath 扁平化,導致版本衝突、傳遞性依賴失控、封裝性缺失——即經典的「依賴地獄」。
Java 編譯時各模組獨立編譯(模組 A 用 C 1.1,模組 B 用 C 1.2),執行時卻合併為單一扁平 classpath,只能載入某一版本,極易引發 LinkageError 或行為不一致。Maven/Ivy 雖能管理構建時依賴,卻無法解決執行期隔離。
Tomcat 等容器為每個 Web 應用建立專屬 ClassLoader,實現類空間隔離:同一 JVM 可同時載入不同版本的 Util.class,互不干擾。這也是熱部署的基礎——丟棄舊 ClassLoader 即釋放所有類供 GC 回收。
| 方案 | 定位 | 關鍵特性 | 成熟度 |
|---|---|---|---|
| OSGi (JSR 291/294) | 運行時動態模組系統 | Manifest 元數據聲明依賴、每 Bundle 專屬 ClassLoader、服務註冊發現、生命週期管理 | 最成熟,Eclipse、JBoss、WebLogic、WebSphere 核心均基於 OSGi |
| Jigsaw (Project Jigsaw) | JDK 內部模組化 | module 關鍵字、編譯期強類型檢查、模組圖解析、jlink 打包自定義運行時映像 | JDK 9 正式納入,JDK 7/8 僅作預覽,非標準化運行時模組系統 |
| Simple Module System (JSR 294 專家組提議) | 統一元數據格式 | Maven Central 庫產出同時兼容 OSGi 與 Jigsaw 的模組元數據,配合編譯器插件生成 | 討論中,旨在統一生態分裂 |
IDE、瀏覽器、建構工具普遍採用 Plugin 模式:宿主定義 API,Plugin 實現並注入。Plugin 本身也是模組,面臨同樣的版本與依賴鏈問題。OSGi 的 Bundle 實質即標準化的 Plugin,具備版本、依賴、生命週期完整語義。
模組化旨在最小化耦合、解決依賴地獄。OSGi 以運行時驗證、ClassLoader 隔離、服務動態綁定在企業級佈署贏得廣泛採用;Jigsaw 則從語言層面解決 JDK 內部模組化,並為未來標準化鋪路。JSR 294 正嘗試定義統一元數據格式,讓同一模組製品能同時在 OSGi、Jigsaw 甚至未來標準運行時運行。對開發者而言,理解 ClassLoader 機制、善用構建工具管理依賴、評估是否引入 OSGi 運行時,是駕馭 Java 模組化複雜度的關鍵。