歷經一波三折,Java SE 9終於在9月21日正式釋出了,從語言層面來看,Java SE 9似乎沒什麼太大變化,不過,你知道下個版本的Java SE版本號可能會是18.3嗎?還有,為什麼更新完JDK之後,IDE就整個無法開啟了?

別忘了,Java SE 9的重大特性之一是模組化,JDK/JRE也因應而做了重新架構。

下個版本是Java 18.3?

在Java走過二十多個年頭的這段期間,JDK曾經有過一些重大的版本號變化,第一個重大版本變更是J2SE 1.2,這個版本就是老一輩Java人最熟悉的Java 2,過去臺灣昇陽舉辦的Java Two研討會也是以此為名,一些開發者口中始終改不了口的J2EE,也是基於此版本,可見此版本之重要性;版本號大躍進,第一次則是發生在J2SE 1.4直跳J2SE 5.0,這是為了彰顯這個版本與之前版本有極大不同,像是語法上的簡化、增加泛型、列舉、標註等重大功能。

然而,J2SE 5.0這版本號又是2又是5的,令人困惑,因而2006年底發表的Java SE決定不再帶有2這個名稱,簡稱Java SE 6,之後版本就基於重大特性,分別又發表了Java SE 7到Java SE 9。

平均來說,在Java SE 6之前,約二年左右會發布Java重大版本,中間則會有一些為了修正臭蟲、安全性而發布的小更新版本。然而,從Java SE 6之後,由於營收、併購或技術、安全性修正等因素,使得發布時程變得沒有規律,經常就是一延再延,重大特性也就被一推再推地放至下個版本,像是Java SE 7的Lambda與Jigsaw,一開始被推至Java SE 8,後來Jigsaw又再度被推延至Java SE 9。

然而,除了重大特性之外,還有許多對開發者有用的小特性,也因此被迫隨著重大版本才能釋出,為此,Oracle的Java架構長Mark Reinhold,在2012年就曾因Jigsaw無法實現於Java SE 8時希望,未來Java的發布可以是基於時間而非基於重大特性,以半年為週期,持續發布新版本,讓一些有用的小特性(例如jshell這種),也能在這些新版本被開發者使用。

因此,從Java SE 9之後有了新的版本號時間軸,Oracle在〈Oracle Java SE Support Roadmap〉(https://goo.gl/7Civd5)指出,未來新的版本號會是基於$YEAR.$MONTH格式,例如,下個版本預計會是2018年3月釋出,因此版本會是Java SE 18.3,以後若發現不是Java SE 9字樣,而是Java SE 18.3這類的字樣,就不要太訝異了。

這樣的版本號模式,對Java來說,有些新鮮,然而,有些語言就是採持續而頻繁地釋出新版本,像是Go語言,而基於時間、非基於重大特性來釋出的軟體,最典型的範例就是Ubuntu。

未來,Java SE 18.3等版本將會是短期支援版本,〈Oracle Java SE Support Roadmap〉指出,在下個小版本釋出後,上個版本就不再維護,使用者要趕快更新版本,Oracle也有Java SE的長期支援版本,三年為週期,可透過Oracle Java SE Advanced、Oracle Java SE Advanced Desktop,或是Java SE Suite取得,另外,Java SE 8會是長期支援版本,將支援至2022年。

JDK/JRE重新架構了!

跟過去安裝完JDK不同,在更新為JDK9之後,有可能發生的最差情況是,IDE等相關開發工具完全無法啟動了,這是因為Java SE 9重新架構了JDK與JRE的實體結構,如果開發工具會試圖尋找rt.jar、tools.jar之類的檔案,很抱歉,JDK9/JRE9中沒有這些檔案(或其他相關目錄),你得升級開發工具至可以支援JDK9/JRE9的版本。

Java SE 9支援模組化,而JDK/JRE本身也為了模組化而重新架構,首先,JDK本身的私用JRE(Private JRE)沒有專屬目錄——Java SE API實作原始碼的部份,改放到lib中的src.zip,而其中細分為java.base等各個模組,若要找到想察看的原始碼,得先知道它們被歸到了哪個模組,之後才是查看對應的套件。

rt.jar、tools.jar之類的檔案,由什麼取代了呢?在JDK中有個jmods目錄,裏頭有一堆.jmod檔案,主檔名為模組名稱,目前它是使用zip格式(未來可能會變更),使用解壓縮軟體開啟對應的模組,就可以察看其中的.class檔案,JMOD檔案對應JAR檔案在編譯時期的角色。

Java SE 9模組平臺系統為了改進效能、安全與維護性,在執行時期會使用模組執行時期映像檔(Modular Run-Time Images),又稱JIMAGE,無論是JDK或公用JRE(Public JRE)的目錄,都會有lib目錄,其中有個modules檔案,若使用javac編譯時加上-version,就會看到執行編譯的過程中,從modules載入了module-info.class及相關類別,modules檔案包含的是.class檔案的執行時期格式,也就是,相當於JAR的.class在執行時期載入JVM之後的角色。

JAR/JMOD/JIMAGE?

身為Java開發者,對於JAR(Java Archive)檔案應是相當熟悉,JAR檔案可用來封裝.java原始碼,或者是編譯好的.class,可以用在編譯或執行時期。

在JDK9中,JAR依舊可以使用,更進一步地用來封裝模組,另外,也支援多版本JAR(Multi-release JAR),可以在JAR檔案中,封裝針對不同JDK的.class檔案,讓新版JDK使用新的.class,而舊版JDK使用舊格式.class,詳情可參考〈JEP 238: Multi-Release JAR Files〉(https://goo.gl/HgcrPG)。

JDK9也引進了新的JMOD格式來封裝模組,目的在於可以處理比JAR更多的檔案類型,像是原生指令、組態檔等,有些文件將JMOD描述為擴充版本的JAR,可以使用JDK9附的jmod工具程式來建立、查看或取出JMOD檔案的內容,在編譯或鏈結(link)時,也就是使用javac或jlink工具程式時,可以指定--module-path引數至.jmod檔案所在路徑,然而執行時期不支援JMOD檔案。你可以查看〈jmod〉(https://goo.gl/pZyQKr)瞭解如何使用jmod工具程式。

在執行時期,JDK9使用的是執行時期映像檔,可以使用JDK9附的jlink工具程式,建立一個專用的執行時期映像檔,其中只包含你指定的模組,使用jlink時的模組來源,可以是模組化的JAR,或者是JMOD,建立後的目錄中,會有java等工具程式。

如果執行時期映像檔中,包含了進入點模組(建立.jmod時可使用--main-class指定),只要執行jlink建立的目錄中之java,並使用-m指定進入點模組名稱即可。而且,執行時期映像檔只用於執行時期,無法用於編譯。你可以查看〈jlink〉(https://goo.gl/bcT8Lx)瞭解如何使用jlink工具程式。

因而JDK9之後,有三種方式可以發布你的程式庫或應用程式。如果只是希望客戶端使用應用程式,發布jlink建立的東西就可以了;如果希望客戶端可以自訂執行時期映像檔,那麼可以發布JMOD;如果是給開發者使用的程式庫,建議採用支援模組化的JAR檔案。

而正如我先前專欄〈Java 9模組化概觀〉中談到的,未來的Java開發生態中,類別路徑應會逐漸淡出,新開發的專案建議採用模組化,並改用模組路徑指定程式庫來源。

不是裝好就沒事了

以往在更新JDK後,相關的開發工具,基本上應該都可以運行而不會有太大問題,然而在更新JDK9之後,若你的開發工具連開都開不起來,別急著對JDK9開罵,先瞭解一下JDK9本身做了哪些改變,然後看看這些工具有沒有更新至支援JDK9的版本。

畢竟JDK9的重大特性就是模組化,也就因此JDK/JRE本身也做了重新架構(正所謂吃自己的狗糧),對於JDK9來說,不能存著裝好就沒事的態度,藉由瞭解JDK9本身如何重新架構,進一步地就會瞭解到JAR的變化,以及JMOD與JIMAGE的存在與目的,對於未來開發程式時如何因應模組化以及如何發布,也就能夠有更深的認識。

作者簡介


Advertisement

更多 iThome相關內容