天天看點

探秘Java9

2017年9月Java9正式釋出,之前就一直聽說新版會有子產品化,仔細了解下Java9的發展史,這個子產品化确實比較坎坷,當然,好事多磨嘛。

1、相關組織

JUG:Java User Groups(Java使用者群),以下是JUG官方提供的組織清單,其中有兩個是大陸的,一個在南京,一個在杭州,個人感覺南京的現在不怎麼活躍了,之前在南京時參加過南京JUG組織的活動。杭州的JUG應該我們公司的同學比較多吧。

探秘Java9
探秘Java9

JCP:Java Community Process,一個促進Java發展的國際組織,主要負責JSR的制定,OpenJDK的開發。其中JUG屬于JCP。

EC:Executive Committee,是JCP中的執行委員會,是選舉産生的,但Oracle是終身的執行委員會(沒辦法,因為JCP也是由SUN(後被Oracle并了)發起的),主要負責JSR的制定,有投票權。這裡列一下曾經的EC成員:Motorola、Nokia、Sony、Samsung、HP、Siemens、Texas Instruments、Apple、Philips、Symbian、JBoss、Google、Ericsson、BenQ、SpringSource、AT&T、VMWare、Aplix、Freescale、Apache、Doug Lea、Timothy Peierls。

2、相關名詞

JEP:JDK Enhancement Proposals(JDK增強建議),來源于JCP社群,但不一定被采納,如果

JSR:Java Specification Requests(Java規範請求),JSR是有狀态的,并不是所有的JSR都有效,是以在看JSR時需要先看下狀态是否有效。Java的各個版本的語言規範和虛拟機規範都是JSR範疇裡的,JSR的生效由Expert Group(專家組)商讨制定并由EC投票确立。JSR的确立是有一個具體流程規範的,不過并不是所有的JSR都會在JDK裡實作的。

JSR專家組(Expert Group):從JCP裡選出的對應領域有威望的個人(其實背後代表的是所屬公司),負責制定和修改JSR。其中Java9對應的JSR379的專家組如下:

探秘Java9

Java語言規範:其實已經包括在JSR裡,細分開是因為隻是語言層面的,不涉及跨平台的JVM的細節,是以想要詳細了解Java文法的可以仔細研讀下。具體代碼裡如何實作的不在規範裡。

JVM規範:這裡主要描述虛拟機的實作規範,包括指令集及期作用、虛拟機記憶體模型、類檔案描述、編譯、連結、加載、初始化等步聚描述,想要了解虛拟機具體是怎麼工作的可以仔細研讀下,不過規範不涉及實作,目前虛拟機的實作也有很多種,HotSpot是OpenJDK裡的,想要了解實作細節的可以下載下傳HotSpot源碼看下。

3、JDK功能的由來

通過上面的一些簡介可以大緻看出,JDK的功能來源于Java開發者在實際使用時發現的一些不足之處,然後以JEP的方式回報給社群,社群再通過專家組收集并制定JSR,再由EC投票是否要采納,對于規劃到Java版本JSR裡的再由JCP配置設定或認領開發實作,經過一系列測試驗證後釋出Release版本。

Java9的規範是JSR379,但379又依賴JSR376,也就是Java的平台子產品化,在JDK9的源碼裡也可以看到“@spec JPMS”,這個表示的是這塊代碼是JSR376裡要求實作或修改的。

個人根據JSR文檔整理了下,共涉及91個JEP,其中8個JEP是關于廢棄的,39個JEP是關于修改的,44個JEP是關于新增的,子產品化涉及8個JEP,安全涉及7個JEP。可以看出Java9不僅僅是子產品化,還帶來很多其他的改變,具體整理JEP如下(前辍說明:U:修改,A:新增,D:廢棄,M:子產品化,S:安全):

6、Java9帶來哪些變化?

通過5中的JEP也可以看出,不過官方給了一個分類:

探秘Java9

7、關于子產品化

因為Java9對于平台來說最大的變化是子產品,涉及到了文法規範和虛拟機的改變,具體有哪些變化呢?其實規範裡這些都特意标出來了,按照正常的思考應該類加載會變,還要就是要麼像OSGI那樣用MANIFEST.MF,要麼就新增加一些關鍵字。實際是增加了一個module-info.java檔案,這個有點像已經有的package-info.java,不過package-info.java其實隻起到注釋包的作用,并沒有什麼新的關鍵字,是以沒有文法不相容的情況,但module-info.java則不同了,個人感覺和OSGI裡的MANIFEST.MF裡的一些用法并沒有什麼不同,但這樣會導緻IDE識别不了這些關鍵字,編譯器就需要有對應的修改才能正常相容。

其實子產品化這個想法早在十幾年前就已經提出來了,而且也有對應的JSR,因為在建構大型的Java應用時會因為使用的Jar有多個版本,根據路徑加載的方式會出現不可控的情況,也就是我們常見的類沖突,因為不同的環境可能會導緻不同的類加載順序,而Java對于相同包名類名的類加載隻有第一次生效,後面的不會再加載,是以對于大型系統的複雜依賴這個問題比較嚴重。還有就是生成的應用越來越大,在嵌入式應用中不太适合。而OSGI最開始也不是子產品化的代名詞,其實OSGI最開始創立的目的應該是像JCP一樣,制定一些網關裝置相關規範的,那時Java在嵌入式領域也有了廣泛的應用,當時看到了Java的不足,提出來JSR291,這才誕生了OSGI架構,經過十多年的發展,已經相當成熟。

不過JSR376也說明了自己與JSR291的差別,JSR291是在平台之上的,不是平台具備的能力,JSR376的目的是讓平台具有子產品化的能力,同時平台的子產品化能力也能夠直接給OSGI架構使用,畢竟OSGI的核心是動态加載的架構。

8、其他關于子產品化的應用

OSGI:為什麼OSGI可以直接基于現有的JDK達到子產品化?其實這個依賴于Java的類加載機制,不同的ClassLoader是可以讓同一個類有多個版本加載的,但同一個ClassLoader不能對同一個類的多個版本進行加載。

Pandora:其實這個我覺得應該算是子產品化的産物,如果十多年前子產品化被納入JDK,也不會有Pandora了吧。實作的原理也是基于類的加載和對應的ClassLoader有關。

Maven:也算是子產品化的應用吧,不過是以pom.xml的方式來管理依賴的,對于沖突也是在pom.xml的依賴管理裡來排,但對于像OSGI和Pandora那樣的類加載方式卻不涉及,完全靠人肉排除多版本依賴的問題,并不能對多差異版本共存的問題有實質性幫助。不過我想Maven的目的并不是解決這個問題的,不擅長也可以了解,Maven主要還是管理依賴和jar包分發,從更上層來避免此類類沖突問題。