JVM 與module-path - OpenHome.cc

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

首先,對於模組平臺系統要知道的第一件事是,它跟Java 程式語言本身沒有關係,而是為了管理程式庫本身的功能封裝、程式庫之間的相依性等需求而存在,將一個不支援模組 ... 回 JavaEssence 首先,對於模組平臺系統要知道的第一件事是,它跟Java 程式語言本身沒有關係,而是為了管理程式庫本身的功能封裝、程式庫之間的相依性等需求而存在,將一個不支援模組的程式庫改為支援模組,基本上不用修改程式庫中的程式碼。

那麼為什麼模組可以改進程式庫的封裝性與相依性?如果你基於A 程式庫撰寫了新的程式庫,接著有同事想要使用你的程式庫,而你不想要他直接呼叫A程式庫的相關功能,以免他撰寫的程式直接依賴在A 程式庫上,就目前你知道的知識來說,只要類別路徑上可以找得到A 程式庫的相關類別,他就可以呼叫相關功能,日後程式庫之間錯綜複雜的相依性就從此開始了,而這也是目前Java生態圈中面臨的重大問題之一。

當然,Java生態圈20 幾年來,也為了這樣的問題提出了解決方案,也有第三方(Third-party)的模組系統,而為了要統一模組平臺的規格,以及為Java SE平臺瘦身(讓小型運算裝置可以依需求下載必要的模組而不是整個JRE)、改進安全等因素,JavaSE9 決定納入模組平台系統成為標準之一。

模組平臺系統跟Java 程式語言本身沒有關係,而且指令上的運用較為複雜,基本上會有相關開發工具代勞指令處理這些細節,不過,透過一些手動建立模組的過程,有助於瞭解模組的基本架構,也比較清 楚開發工具大致上代勞了哪些細項。

那麼就來開始建立第一個模組吧!首先看看,一個未支援模組的程式專案要如何設定,才能使之成為模組。

請複製範 例檔資料夾中的Hello2資料夾至C:\workspace,Hello2中有個src資料夾,其中有 cc\openhome\Main.java檔案,你應該已經懂得它撰寫的內容了: packagecc.openhome; publicclassMain{ publicstaticvoidmain(String[]args){ System.out.println("Hello,World"); } } 根據先前幾個小節的介紹,你應該知道在進入Hello2資料夾後,可以使用底下的指令來編譯並執行程式: javac-dclassessrc/cc/openhome/Main.java java-cpclassescc.openhome.Main 這是基於類別路徑的方式,若想要設定它為模組,第一件事是決定模組名稱,這邊假設模組名稱為cc.openhome, 建議建立一個與模組名稱相同的資料夾,然後其中依套件設定的階層放入原始碼,在這邊可以在src中建立cc.openhome 資料夾,然後將原先src中的cc資料夾放到cc.openhome資料夾之中: 接下來,在cc.openhome資料夾中建立一個module-info.java並撰寫底下內容: 這麼一來,在原始碼層面上,你就建立了第一個模組了,雖然module-info.java 的副檔名為.java,它實際上只是個設定檔,其中的module關鍵字僅在這個設定檔中進行設定之用,不是 Java程式語言的一部份,副檔名為.java,單純只是為了相容性,讓javac 等工具程式易於處理這個設定檔罷了。

上圖的module關鍵字定義了模組名稱為cc.openhome,除此之外 沒有其他設定,這表示目前只能存取同一模組以及Java標準API的java.base模組,java.base 模組中包含了像是java.lang等常用的套件;言下之意也表示,日後必要的話,可以在 module-info.java中設定自己的模組可以公開哪些API,或者是依賴在哪個模組之上。

那麼來編譯程式碼吧!可以將編譯出來的類別放在mods資料夾中對應模組名稱的資料夾之中: 這麼一來,mods中的cc.openhome就是你第一個編譯成功的模組了,其他開發者若要使用這個模組,可以在執行java 時,透過--module-path指定模組路徑。

由於Main.java中實際上撰寫了程式進入點,如果想要執行它的話,可以透過-m 指定模組的程式進入點,例如: 圖中使用了--module-path指定了模組路徑,而不是使用-classpath 指定類別路徑,這個時候要注意的是,在完全吻合名稱之前還要指定模組名稱,然而,這僅僅只是工具層面的需求,在程式碼撰寫上,使用模組中的 API並不用進行任何變更。

基於相容性,模組也可以基於類別路徑來使用,方式與先前的說明是相同的,例如: 按照規範,在類別路徑下被發現的類別,都會被自動歸類到一個未命名的模組(unnamed module),就目前來說,你只要知道這些類別彼此之間的可見性,與JavaSE8 或先前版本的可見性相同就可以了,如果馬上就想進一步認識未命名模組,可以參考〈The unnamedmodule〉中的介紹。



請為這篇文章評分?