Java 9模組化概觀 - iThome

文章推薦指數: 80 %
投票人數:10人

而在最新的JDK9預覽版中,也可以玩玩Java模組平臺系統(Java Platform Module System),也就是JSR376的實作了。

JAR檔案的挑戰. 撰寫Java的開發者都知道 ... 移至主內容 文/林信良 | 2017-03-12發表 從Java7開始,就一直嚷嚷著要納入的模組化架構,到了Java8不見推出,這中間又過了好幾年,最後來到了Java9,而Java9又因開發不及,從原定的2017年3月改到了2017年7月,如果沒有意外,目前看來,應該是可以如期推出。

而在最新的JDK9預覽版中,也可以玩玩Java模組平臺系統(JavaPlatformModuleSystem),也就是JSR376的實作了。

JAR檔案的挑戰 撰寫Java的開發者都知道,目前的Java使用JAR檔案來包裝一堆類別檔案,而這些類別檔案會使用套件(package)來加以組織,在編譯或運行Java應用程式時,必須指定類別路徑(CLASSPATH),一開始這不是什麼問題,只是隨著Java應用的場合越來越多,挑戰也就越來越多。

舉例而言,JAR檔案定義在類別路徑中的順序,經常會有同名類別遮蓋的問題;JAR對包裝的類別沒有封裝機制,即使開發中的程式庫想隱藏底層使用到的實作品,然而,只要是public的類型,對客戶端就是可見的;簡而言之,JAR檔案充其量只是個方便傳送的器皿罷了,它沒辦法表示彼此之間的依賴關係,想想看,有多少次發生ClassNotFoundException時,你總是想不透,到底還缺少了哪個JAR檔案呢? JavaSE自己也身受其害。

從10MB以下的JDK1.1,到現在200多MB的JDK8,JDK越來越肥大,在錯綜複雜的依賴關係下,有些標準API就算不需要,也必須全盤接受,這對現今的IoT是個挑戰,雖然Java8之後有了compactprofile,可定義三種JavaSE的子集,然而,也只是在有限程度下緩解了這個問題。

而且,還有更多其他的問題待解決,這部份可以參考〈ProjectJigsawisReallyCominginJava9〉(https://goo.gl/15XuYl),某些工具試圖解決部份問題,像是Maven、OSGi等,然而由於一些技術、政治或商業性考量,Java9終究是採用了Jigsaw來解決(部份的)問題。

類別路徑淡出,模組路徑登場 具體來說,Java9中的模組仍是使用JAR檔案,這是為了善用現有的工具,以緩解導入或遷移的負擔,一個模組化JAR檔案(modularJARfile)與一般JAR檔案之間的差別,在於根目錄下是否包含一個module-info.class,而它又是由一個module-info.java檔案編譯而來,這個.java是作為模組描述器(Moduledescriptor)使用。

一個最簡單的模組描述器,可以只包括modulecc.openhome.app{}這樣的內容,雖然是個.java檔案,但它不是Java原始碼,開發者不用擔心module成為保留字,而影響了既有的Java原始碼,因為這一個不是Java的.java,以及編譯出來的.class,只是讓編譯器或執行環境能理解這是一個模組。

模組名稱必須是唯一的,與套件名稱類似的,建議使用網域名稱的相反模式,通常是套件名稱的前置部份,如果應用程式依賴在某些模組,在編譯的時候,必須使用--module-path(簡寫-p)或--module-source-path來指定模組路徑,執行時也要指定--module-path,或者是在想要指定起始模組時使用--module(簡寫-m)。

在Java9推出之後,未來在開發上當然是鼓勵定義模組的,而類別路徑的指定方式,基於向後相容性(Backwardcompatibility)考量仍舊支援,實際上,一個模組化JAR檔案若是指定於類別路徑中,就會被當成是一般JAR檔案,然而,類別路徑未來應走向逐漸淡出的道路,既有的程式庫在可能的情況下,也要逐漸遷移至新的模組系統。

模組描述器概觀 最簡單的module-info.java,可以只包括modulecc.openhome.app{},這樣的模組描述器沒有指定任何依賴模組,這表示它依賴在最基本的java.base模組(若使用到java.sql等其他模組,就會編譯失敗)。

JavaSE9將過往有著錯綜複雜依賴關係的標準API,畫分為java.logging、java.sql、java.xml等各個模組,而這些模組最終都依賴在一個java.base模組,它包含了java.lang、java.io等基本套件,而整個JavaSE被定義為一個java.se模組。

一個有著依賴關係的模組描述器,會像是: modulecc.openhome.app{ requirescc.openhome.openscad; requirespubliccc.openhome.math; exportscc.openhome.turtle; }這部分表示了一些事情——cc.openhome.app模組依賴在cc.openhome.openscad,以及前者的類別對後者匯出(exports)的公開類別,具有讀取性(Readability)。

而且,要注意的是,讀取性僅定義了模組的依賴關係圖,例如cc.openhome.app對cc.openhome.openscad是顯式(explicitly)依賴,然而,cc.openhome.openscad可能依賴在其他模組上,因而這些模組也被cc.openhome.app隱式(implicitly)依賴,而對於modulecc.openhome.app{},它也隱式依賴在java.base。

只有讀取性,並不代表著可使用被依賴模組中的類別,例如,若有模組requirescc.openhome.app,而上面的模組描述器中並沒有exportscc.openhome.turtle的話(cc.openhome.app中定義的套件),那麼就無法使用cc.openhome.turtle套件中的類別,這表示被public定義的類別不再是全域可見了,定義模組時可以使用exports決定其存取性(Accessibility),因而模組可以實現更強的封裝性(Strongencapsulation)。

有一個問題是,如果有模組requirescc.openhome.app,而cc.openhome.openscad模組中,傳回了cc.openhome.math套件中的類別類型,那麼,最前頭的模組可以也使用該類型嗎? 對此,簡單的想法是,讓開發者自行在一開始的模組描述器,也加上requirescc.openhome.openscad,不過,這作法麻煩也不可靠,如果cc.openhome.app願意的話,只要加上requirespubliccc.openhome.math,就可以解決這個問題。

相容性與遷移 無疑地,既有的應用程式,還是要能在Java9上運行的,其中一個作法如前所述,一個模組化JAR檔案若是指定於類別路徑中,會被當成是一般JAR檔案,實際上,置於類別路徑中的類別,都會被歸類在一個未命名模組(unnamedmodule),未命名模組對任何模組都具有讀取性,對被模組匯出的套件中的任何類別具有存取性。

而在既有程式庫的遷移上,有一個簡單的情境是,如果某個JAR檔案未依賴類別路徑上的其他程式庫,而且經檢查僅依賴在java.base模組,那麼,這個JAR檔案可以進一步定義為模組化檔案;接著,若另一個JAR檔案依賴在這個JAR,就可以定義其依賴在新定義的模組,以及其他的java.sql等模組上,依此類推、完成遷移。

整體而言,這是一種自底而上的遷移(Bottom-upmigration)方式。

當然,實際的依賴情況可能更複雜,可以使用jdeps之類的工具來檢查相依關係,而開發者也需要瞭解更多模組化的細節,此時,SimonRitter的演講〈ProjectJigsawinJDK9:ModularityComesToJava〉(https://goo.gl/3Scf6n)會是個好的開始。

在這之後,OpenJDK官方的〈TheStateoftheModuleSystem〉(https://goo.gl/HFN9Em)是個詳盡的文件。

專欄作者 林信良 因在網路上經營「良葛格學習筆記」(openhome.cc)而聞名,曾任昇陽教育訓練中心技術顧問、甲骨文教育訓練中心授權講師,目前為自由工作者,專長為技術寫作、翻譯與教育訓練。

喜好研究程式語言、框架、社群,從中學習設計、典範及文化。

閒暇之餘記錄所學,技術文件涵蓋C/C++、Java、Ruby/Rails、Python、JavaScript、Haskell等多個領域。

熱門新聞 Chrome與Edge中的拼字檢查功能可能外洩用戶密碼 2022-09-19 Uber疑似被駭,內部多項系統遭取得權限 2022-09-19 以太坊合併後,GPU挖礦已幾乎無利可圖 2022-09-19 全家史上最大規模POS改造,不只砸上億導混合雲,雙模式三大設計一機通吃大小店種和戶外擺攤 2022-09-15 【資安週報】2022年9月12日到9月16日 2022-09-18 與Nvidia關係決裂?EVGA退出顯示卡市場 2022-09-19 星巴克22萬新加坡顧客資料遭駭客公開兜售 2022-09-19 【資安日報】2022年9月19日,Uber特權管理系統管理員帳密遭竊、密碼管理解決方案業者LastPass針對8月遭駭透露更多調查結果 2022-09-19 Advertisement 2022iThome鐵人賽 專題報導 iThome2022資安大調查(下) iThome2022資安大調查(上) 【iThome2022CIO大調查(下)】各產業數位轉型加速,IT大步邁向雲原生 分散式RAID躍居主流儲存應用 【iThome2022CIO大調查(中)】企業IT新戰力 更多專題報導



請為這篇文章評分?