探祕Java9
2017年9月Java9正式釋出,之前就一直聽說新版會有模組化,仔細瞭解下Java9的發展史,這個模組化確實比較坎坷,當然,好事多磨嘛。
1、相關組織
JUG:Java User Groups(Java使用者群),以下是JUG官方提供的組織列表,其中有兩個是大陸的,一個在南京,一個在杭州,之前在南京時參加過南京JUG組織的活動。
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的專家組如下:
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裡要求實現或修改的。
5、JSR 379: JavaTM SE 9 Release Contents涉及哪些JEP?
個人根據JSR文件整理了下,共涉及91個JEP,其中8個JEP是關於廢棄的,39個JEP是關於修改的,44個JEP是關於新增的,模組化涉及8個JEP,安全涉及7個JEP。可以看出Java9不僅僅是模組化,還帶來很多其他的改變,具體整理JEP如下(前輟說明:U:修改,A:新增,D:廢棄,M:模組化,S:安全):
U 102: Process API Updates
A 110: HTTP 2 Client
U 143: Improve Contended Locking
U 158: Unified JVM Logging
U 165: Compiler Control
U 193: Variable Handles
U 197: Segmented Code Cache
U 199: Smart Java Compilation, Phase Two
AM 200: The Modular JDK
AM 201: Modular Source Code
A 211: Elide Deprecation Warnings on Import Statements
A 212: Resolve Lint and Doclint Warnings
U 213: Milling Project Coin
D 214: Remove GC Combinations Deprecated in JDK 8
A 215: Tiered Attribution for javac
U 216: Process Import Statements Correctly
U 217: Annotations Pipeline 2.0
A 219: Datagram Transport Layer Security (DTLS)
AM 220: Modular Run-Time Images
A 221: Simplified Doclet API
A 222: jshell: The Java Shell (Read-Eval-Print Loop)
A 223: New Version-String Scheme
U 224: HTML5 Javadoc
A 225: Javadoc Search
A 226: UTF-8 Property Files
A 227: Unicode 7.0
A 228: Add More Diagnostic Commands
US 229: Create PKCS12 Keystores by Default
D 231: Remove Launch-Time JRE Version Selection
U 232: Improve Secure Application Performance
A 233: Generate Run-Time Compiler Tests Automatically
A 235: Test Class-File Attributes Generated by javac
A 236: Parser API for Nashorn
A 237: Linux/AArch64 Port
U 238: Multi-Release JAR Files
D 240: Remove the JVM TI hprof Agent
D 241: Remove the jhat Tool
A 243: Java-Level JVM Compiler Interface
US 244: TLS Application-Layer Protocol Negotiation Extension
U 245: Validate JVM Command-Line Flag Arguments
US 246: Leverage CPU Instructions for GHASH and RSA
U 247: Compile for Older Platform Versions
U 248: Make G1 the Default Garbage Collector
AS 249: OCSP Stapling for TLS
U 250: Store Interned Strings in CDS Archives
A 251: Multi-Resolution Images
U 252: Use CLDR Locale Data by Default
A 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
U 254: Compact Strings
U 255: Merge Selected Xerces 2.11.0 Updates into JAXP
U 256: BeanInfo Annotations
U 257: Update JavaFX/Media to Newer Version of GStreamer
U 258: HarfBuzz Font-Layout Engine
A 259: Stack-Walking API
UM 260: Encapsulate Most Internal APIs
AM 261: Module System
U 262: TIFF Image I/O
A 263: HiDPI Graphics on Windows and Linux
A 264: Platform Logging API and Service
U 265: Marlin Graphics Renderer
U 266: More Concurrency Updates
A 267: Unicode 8.0
A 268: XML Catalogs
A 269: Convenience Factory Methods for Collections
U 270: Reserved Stack Areas for Critical Sections
U 271: Unified GC Logging
A 272: Platform-Specific Desktop Features
A 273: DRBG-Based SecureRandom Implementations
U 274: Enhanced Method Handles
AM 275: Modular Java Application Packaging
AM 276: Dynamic Linking of Language-Defined Object Models
U 277: Enhanced Deprecation
A 278: Additional Tests for Humongous Objects in G1
U 279: Improve Test-Failure Troubleshooting
U 280: Indify String Concatenation
A 281: HotSpot C++ Unit-Test Framework
AM 282: jlink: The Java Linker
A 283: Enable GTK 3 on Linux
U 284: New HotSpot Build System
A 285: Spin-Wait Hints
AS 287: SHA-3 Hash Algorithms
DS 288: Disable SHA-1 Certificates
D 289: Deprecate the Applet API
AS 290: Filter Incoming Serialization Data
D 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
A 292: Implement Selected ECMAScript 6 Features in Nashorn
A 294: Linux/s390x Port
A 295: Ahead-of-Time Compilation
U 297: Unified arm32/arm64 Port
D 298: Remove Demos and Samples
U 299: Reorganize Documentation
6、Java9帶來哪些變化?
通過5中的JEP也可以看出有9帶來了哪些變化,不過官方還是給了一個分類如下:
主要分為:平臺、語言、核心庫、網路、安全、客戶端庫、擴充標記語言 這7類。
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包分發,從更上層來避免此類衝突問題。
相關文章
- 探祕WKWebViewWebView
- Web列印探祕Web
- Cglib proxy探祕CGLib
- 探祕intern()方法
- TaskContinuationsOptions.ExecuteSynchronously探祕
- 深度探祕.NET 5.0
- Java 隨機數探祕Java隨機
- 【NIO系列】——之TCP探祕TCP
- MySQL InnoDB 儲存引擎探祕MySql儲存引擎
- JVM系列(三) - JVM物件探祕JVM物件
- Vue原始碼探祕(七)(createElement)Vue原始碼
- Vue原始碼探祕(九)(createComponent)Vue原始碼
- 探祕 Mach-O 檔案Mac
- PHP現代化框架探祕PHP框架
- Amazon Corretto技術細節探祕
- Elastic 探祕之遺落的珍珠AST
- SpringBoot修行之路-3.探祕SpringApplicationSpring BootAPP
- MySQL探祕(八):InnoDB的事務MySql
- Koa:核心探祕與入坑指北
- RocketMQ 5.0 POP 消費模式探祕MQ模式
- 探索JAVA系列(一)探祕Java反射(Reflect)Java反射
- php 核心探祕之 PHP_FUNCTION 巨集PHPFunction
- 群邑報告:探祕越南農村
- RocketMQ(七):高效能探祕之MappedFileMQAPP
- SpringBoot 應用程式啟動過程探祕Spring Boot
- 探祕varian:優雅的釋出部署程式
- 探祕Android黑科技-ViewModel如何無視ConfigurationChangeAndroidView
- 資本深探:搜狐突然盈利的祕密
- 現代瀏覽器探祕(part3):渲染瀏覽器
- Vue原始碼探祕(四)(例項掛載$mount)Vue原始碼
- systemtap 探祕(三)- 型別、變數和陣列型別變數陣列
- 【Vue原始碼學習】響應式原理探祕Vue原始碼
- 室友的Zip加密檔案探祕,Python解決Zip加密檔案探索祕密!加密Python
- 現代瀏覽器探祕(part2):導航瀏覽器
- 探祕蘇寧金融升級版秒殺系統
- Vue原始碼探祕(五)(_render 函式的實現)Vue原始碼函式
- Vue原始碼探祕(三)(new Vue發生了什麼?)Vue原始碼
- 沃趣科技李春:MySQL併發複製探祕MySql