VOOZH about

URL: https://read01.com/zh-tw/doMDL7.html

⇱ Java 9終於要包含Jigsaw項目了 - 壹讀


Sunday, Apr 12, 2026

Java 9終於要包含Jigsaw項目了

2016/02/03 來源:InfoQ中文站

當Jigsaw在Java 9中最終發布時,這個項目的歷史已經超過八年了。

在最初的幾年中,它必須要與另外兩個類似的Java規範請求(Java Specification Request)進行競爭,這兩個規範名為JSR 277 Java模塊系統(Java Module System)以及JSR 294 增強的模塊化支持(Improved Modularity Support)。它還導致了與OSGi社區的衝突,人們擔心Jigsaw項目會成為不必要且不完備的功能性重複,逼迫Java開發人員必須在兩種互不兼容的模塊系統中做出選擇。

在早期,這個項目並沒有充足的人手,在2010年Sun併入Oracle的時候,甚至一度中斷。直到2011年,在Java中需要模塊系統的強烈需求被重申,這項工作才得到完全恢復。

接下來的三年是一個探索的階段,結束於2014年的7月,當時建立了多項Java增強提議( Java Enhancement Proposal),包括JEP 200 模塊化JDK(Modular JDK)JEP 201 模塊化源碼(Modular Source Code)JEP 220 模塊化運行時鏡像(Modular Run-Time Image),以及最終的JSR 376 Java平台模塊系統(Java Platform Module System)。上述的最後一項定義了真正的Java模塊系統,它將會在JDK中以一個新JEP的形式來實現。

在2015年7月,JDK劃分為哪些模塊已經大致確定(參見JEP 200),JDK的源碼也進行了重構來適應這種變化(參見JEP 201),運行時鏡像(run-time image)也為模塊化做好了準備(參見JEP 220)。所有的這些都可以在當前JDK 9的預覽版中看到。

針對JSR 376所開發的代碼很快將會部署到JDK倉庫中,但是令人遺憾的是,現在模塊化系統本身尚無法體驗。(目前,Java 9的預覽版本已經包含了模塊化功能。——譯者注)

驅動力

在Jigsaw項目的歷史中,它的驅動力也發生過一些變化。最初,它只是想模塊化JDK。但是當人們意識到如果能夠在庫和應用程式的代碼中也使用該工具的話,將會帶來非常大的收益,於是它的範圍得到了擴展。

不斷增長且不可分割的Java運行時

Java運行時的大小在不斷地增長。但是在Java 8之前,我們並沒有辦法安裝JRE的子集。所有的Java安裝包中都會包含各種庫的分發版本,如XML、SQL以及Swing的API,不管我們是否需要它們,都要將其包含進來。

對於中等規模(如桌面PC和筆記本電腦)以上的計算設備來說,這不算是什麼嚴重的問題,但是對於小型的設備來說,這就很嚴重了,比如在路由器、TV盒子和汽車上,還有其他使用Java的小地方。隨著當前容器化的趨勢,在伺服器領域也有相關的要求,因為減少鏡像的大小就意味著降低成本。

Java 8引入了compact profile的功能,它們定義了三個Java SE的子集。在一定程度上緩解了這個問題,但是它們只有在嚴格限制的場景下才能發揮作用,profile過於死板,無法涵蓋現在和未來所有使用JRE部分功能的需求。

JAR/Classpath地獄

JAR地獄和Classpath地獄是一種詼諧的說法,指的是Java類加載機制的缺陷所引發的問題。尤其是在大型的應用中,它們可能會以各種方式產生令人痛苦的問題。有一些問題是因為其他的問題而引發的,而有一些則是獨立的。

無法表述依賴

JAR文件無法以一種JVM能夠理解的方式來表述它依賴於哪些其他的JAR。因此,就需要用戶手動識別並滿足這些依賴,這要求用戶閱讀文檔、找到正確的項目、下載JAR文件並將其添加到項目中。

而且,有一些依賴是可選的,只有用戶在使用特定功能的特性時,某個JAR才會依賴另外一個JAR。這會使得這個過程更加複雜。

Java運行時在實際使用某項依賴之前,並不能探測到這個依賴是無法滿足的。如果出現這種情況,將會出現NoClassDefFoundError異常,進而導致正在運行的應用崩潰。

像Maven這樣的構建工具能夠幫助解決這個問題。

傳遞性依賴

一個應用程式要運行起來可能只需依賴幾個庫就足夠了,但是這些庫又會需要一些其他的庫。問題組合起來會變得更加複雜,在所消耗的體力以及出錯的可能性上,它會呈指數級地增長。

同樣,構建工具能夠在這個問題上提供一些幫助。

遮蔽

有時候,在classpath的不同JAR包中可能會包含全限定名完全相同的類,比如我們使用同一個庫的兩個不同版本。因為類會從classpath中的第一個JAR包中加載,所以這個版本的變種將會「遮蔽」所有其他的版本,使它們變得不可用。

如果這些不同的變種在語義上有所差別,那將會導致各種級別的問題,從難以發現的不正常行為到非常嚴重的錯誤都是有可能的。更糟糕的是,問題的表現形式是不確定的。這取決於JAR文件在classpath中的順序。在不同的環境下,可能也會有所區別,例如開發人員的IDE與代碼最終運行的生產機器之間就可能有所差別。

版本衝突

如果項目中有兩個所需的庫依賴不同版本的第三個庫,那麼將會產生這個問題。

如果這個庫的兩個版本都添加到classpath中的話,那麼最終的行為是不可預知的。首先,因為前面所述的遮蔽問題,兩個版本的類中,只會有一個能夠加載進來。更糟糕的是,如果某個類位於一個JAR包中,但是它所訪問的其他類卻不在這個包中,這個類也能夠加載。所導致的結果就是,對這個庫的代碼調用將會混合在兩個版本之中。

在最好的情況下,如果試圖訪問所加載的類中不存在的代碼,將會導致明顯的錯誤。但是在最壞的情況下,版本之間的差別僅僅是在語義上,實際的行為會有細微的差別,這會引入很難發現的bug。

識別這種情況所導致的難以預料的行為是很困難的,也無法直接解決。

複雜的類加載機制

默認情況下,所有的類由同一個ClassLoader負責加載,在有些場景下,可能有必要引入額外的加載器,例如允許用戶加載新的類,對應用程式進行擴展。

這很快就會導致複雜的類加載機制,從而產生難以預期和難以理解的行為。

在包之間,只有很弱的封裝機制

如果類位於同一個包中,那Java的可見性修飾符提供了一種很棒的方式來實現這些類之間的封裝。但是,要跨越包之間邊界的話,那只能使用一種可見性:public

因為類加載器會將所有加載進來的包放在一起,public的類對其他所有的類都是可見的,因此,如果我們想創建一項功能,這項功能對某個JAR是可用的,而對於這個JAR之外是不可用的,這是沒有辦法實現的。

手動的安全性

包之間弱封裝性所帶來的一個直接結果就是,安全相關的功能將會暴露在同一個環境中的所有代碼面前。這意味著,惡意代碼有可能繞過安全限制,訪問關鍵的功能。

從Java 1.1開始,有一種hack的方式,能夠防止這種狀況:每當進入安全相關的代碼路徑時,將會調用SecurityManager,並判斷是不是允許訪問。更精確地講,它應該在每個這樣的路徑上都進行調用。過去,在有些地方遺漏了對它們的調用,從而出現了一些漏洞,這給Java帶來了困擾。

啟動性能

最後,Java運行時加載並JIT編譯全部所需的類需要較長的時間。其中一個原因在於類加載機制會對classpath下的所有JAR執行線性的掃描。類似的,在識別某個註解的使用情況時,需要探查classpath下所有的類。

目標

Jigsaw項目的目標就是解決上面所述的問題,它會引入一個語言級別的機制,用來模塊化大型的系統。這種機制將會用在JDK本身中,開發人員也可以將其用於自己的項目之中。

需要注意的是,對於JDK和我們開發人員來說,並不是所有的目標都具有相同的重要性。有一些與JDK具有更強的相關性,並且大多數都對日常的編程不會帶來巨大的影響(這與最近的語言修改形成了對比,如lambda表達式和默認方法)。不過,它們依然會改變大型項目的開發和部署。

可擴展性的平台

JDK在模塊化之後,用戶就能挑出他們需要的功能,並創建自己的JRE,在這個JRE中只包含他們需要的模塊。這有助於在小型設備和容器領域中,保持Java作為關鍵參與者的地位。

在這個提議的規範中,允許將Java SE平台及其實現分解為一組組件,開發人員可以把這些組件組裝起來,形成自定義的配置,裡面只包含應用實際需要的功能。——JSR 376

ArchSummit深圳2016將於7月15-16在華僑城洲際大酒店舉行,3月20日前立減2040元

可靠的配置

通過這個規範,某個模塊能夠聲明對其他模塊的依賴。運行時環境能夠在編譯期(compile-time)、構建期(build-time)以及啟動期(launch-time)分析這些依賴,如果缺少依賴或依賴衝突的話,很快就會發生失敗。

強封裝

Jigsaw項目的一個主要目標就是讓模塊只導出特定的包,其他的包是模塊私有的。

模塊中的私有類就像是類中的私有域。換句話說,模塊的邊界不僅確定了類和接口的可見性,還定義了它的可訪問性。——Mark Reinhold所撰寫的文章「Project Jigsaw:將宏偉藍圖轉換為可聚焦的點」

提升安全性和可維護性

在模塊中,內部API的強封裝會極大地提升安全性,因為核心代碼對於沒有必要使用它們的其餘代碼來講是隱藏起來的。維護也會變得更加容易,這是因為我們能夠更容易地將模塊的公開API變得更小。

隨意使用Java SE平台實現的內部API不僅有安全風險,而且也會帶來維護的負擔。該提議規範能夠提供強封裝性,這樣實現Java SE平台的組件就能阻止對其內部API的訪問。 ——JSR 376

提升性能

因為能夠更加清晰地界定所使用代碼的邊界,現有的優化技術能夠更加高效地運用。

很多預先(ahead-of-time)優化和全程序(whole-program)優化的技術會更加高效,因為能夠得知某個類只會引用幾個特定組件中的類,它並不能引用運行時所加載的任意類。 ——JSR 376

核心概念

因為模塊化是目標,所以Jigsaw項目引入了模塊(module)的概念,描述如下:

命名、自描述的程序組件,會包含代碼和數據。模塊必須能夠包含Java類和接口,組織為包的形式,同時也能以動態加載庫的形式(dynamically-loadable library)包含原生代碼。模塊的數據必須能夠包含靜態資源文件和用戶可編輯的配置文件。 ——Java平台模塊系統:需求(草案2)

為了能夠基於一定的上下文環境來了解模塊,我們可以想一下知名的庫,如Google GuavaApache Commons中的庫(比如Collections或IO),將其作為模塊。根據作者希望劃分的粒度,每個庫都可能劃分為多個模塊。

對於應用來說也是如此。它可以作為一個單體(monolithic)的模塊,也可以進行拆分。在確定如何將其劃分為模塊時,項目的規模和內聚性將是重要的因素。

按照規劃,在組織代碼時,模塊將會成為開發人員工具箱中的常規工具。

開發人員目前已經能夠考慮到一些標準的程序組件,如語言層面的類和接口。模塊將會是另外一種程序組件,像類和接口一樣,它們將會在程序開發的各個階段發揮作用。 ——Mark Reinhold的文章「Project Jigsaw:將宏偉藍圖轉換為可聚焦的點」

模塊又可以進一步組合為開發階段的各種配置,這些階段也就是編譯期、構建期、安裝期以及運行期。對於我們這樣的Java用戶來說,可以這樣做(在這種情況下,通常會將其稱之為開發者模塊),同時這種方式還可以用來剖析Java運行時本身(此時,它們通常稱之為平台模塊)。

實際上,這就是JDK目前進行模塊化的規劃。

(點擊放大圖像)

👁 Image
...
特性

那麼,模塊是如何運行的呢?查閱一下Jigsaw項目的需求以及JSR 376將會幫助我們對其有所了解。

依賴管理

為了解決「JAR/Classpath地獄」的問題,Jigsaw項目的一個關鍵特性就是依賴管理。讓我們看一下這些相關的組件。

聲明與解析

模塊將會聲明它需要哪些其他的模塊才能編譯和運行。模塊系統會使用該信息傳遞性地識別所有需要的模塊,從而保證初始的那個模塊能夠編譯和運行。

我們還可以不依賴具體的模塊,而是依賴一組接口。模塊系統將會試圖據此識別模塊這些模塊實現了所依賴的接口能夠滿足依賴系統會將其綁定到對應的接口中。

版本化

模塊將會進行版本化。它們能夠標記自己的版本(在很大程度上可以是任意格式,只要能夠完全表示順序就行),版本還能用於限制依賴。在任意階段都能覆蓋這兩部分信息。模塊系統會在各個階段都強制要求配置能夠滿足所有的限制。

Jigsaw項目不一定會支持在一個配置中存在某個模塊的多個版本。但是,稍等,那該如何解決JAR地獄的問題呢?好問題!

版本選擇——針對同一個模塊,在一組不同版本中挑選最合適的版本——並沒有作為規範所要完成的任務。所以,在我撰寫的上文中,模塊系統會識別所需的模塊進行編譯,在運行時則可能會使用另外一個模塊,這都基於一個假設,那就是環境中只存在模塊的一個版本。如果存在多個版本的話,那麼上游的步驟(如開發人員或者他所使用的構建工具)必須要做出選擇,系統只會校驗它能滿足所有的約束。

模塊系統會在各個階段強制要求強封裝。這是圍繞著一個導出機制實現的,在這種情況下,只有模塊導出的包才能訪問。封裝與SecurityManager所執行的安全檢查是相獨立的。這個提議的具體語法尚沒有定義,但是JEP 200提供了一些關鍵語義的XML實例。作為樣例,如下的代碼聲明了java.sql模塊。<module> <!-- 模塊的名字 --> <name>java.sql</name> <!-- 每個模塊都會依賴java.base --> <depend>java.base</depend> <!-- 這個模塊依賴於java.logging和java.xml 模塊,並重新導出這些模塊所導出的API包 --> <depend re-exports="true">java.logging</depend> <depend re-exports="true">java.xml</depend> <!-- 這個模塊導出java.sql、javax.sql以及 javax.transaction.xa包給其他任意的模塊 --> <export><name>java.sql</name></export> <export><name>javax.sql</name></export> <export><name>javax.transaction.xa</name></export> </module>從這個代碼片段我們可以看出,java.sql依賴於java.basejava.logging以及java.xml。在稍後介紹不同的導出機制時,我們就能理解上文中其他的聲明了。

導出

模塊會聲明特定的包進行導出,只有包含在這些包中的類型才能導出。這意味著其他模塊只能看到和使用這些類型。更嚴格是,其他模塊必須要顯式聲明依賴包含這些類型的模塊,這些類型才能導出到對應的模塊中

非常有意思的是,不同的模塊能夠包含相同名稱的包,這些模塊甚至還能夠將其導出

在上面的樣例中,java.sql導出了java.sqljavax.sql以及javax.transaction.xa這些包。

重新導出

我們還能夠在某個模塊中重新導出它所依賴的模塊中的API(或者是其中的一部分)。這將會對重構提供支持,我們能夠在不破壞依賴的情況下拆分或合併模塊,因為最初的依賴可以繼續存在。重構後的模塊可以導出與之前相同的包,即便它們可能不會包含所有的代碼。在極端的情況下,有一種所謂的聚合器模塊(aggregator module),它可以根本不包含任何代碼,只是作為一組模塊的抽象。實際上,Java 8中所提供的compact profile就是這樣做的。

從上面的例子中,我們可以看到java.sql重新導出了它依賴的API,即java.loggingjava.xml

限制導出

為了幫助開發者(尤其是模塊化JDK的人員)讓他們所導出API的有較小的接觸面,有一種可選的限制導出(qualified export)機制,它允許某個模塊將一些包聲明為只針對一組特定的模塊進行導出。所以使用「標準」機制時,導出功能的模塊並不知道(也不關心)誰會訪問這些包,但是通過限制導出機制,能夠讓一個模塊限定可能產生的依賴。

配置、階段以及保真性(Fidelity)

如前所述,JEP 200的目標之一就是模塊能夠在開發的各個階段組合為各種配置。對於平台模塊可以如此,這樣就能夠創建與完整JRE或JDK類似的鏡像,Java 8所引入的compact profile以及包含特定模塊集合(及其級聯依賴)的任意自定義配置都使用了這種機制。類似的,開發人員也可以使用這種機制來組合他們應用程式的不同變種。

編譯期(compile-time),要編譯的代碼只能看到所配置的模塊集合中導出的包。在構建期(build-time),藉助一個新的工具(可能會被稱為JLink),我們能夠創建只包含特定模塊及其依賴的二進位運行時鏡像。在安裝期(launch-time),鏡像能夠看起來就像是只包含了它所具有的模塊的一個子集。

我們還能夠替換實現了授權標準(endorsed standard)獨立技術(standalone technology)的模塊,在任意的階段都能將其替換為較新的版本。這將會替代已廢棄的授權標準重載機制(endorsed standards override mechanism)以及擴展機制(參見下文。)

模塊系統的各個方面(如依賴管理、封裝等等),在所有階段的運行方式是完全相同的,除非因為特定的原因,在某些階段無法實現。

模塊相關的所有信息(如版本、依賴以及包導出)都會在代碼文件中進行描述,這樣會獨立於IDE和構建工具。

性能

全程序優化的技術

在模塊系統中,藉助強封裝技術,能夠很容易自動計算出一段特定的代碼都用在了哪些地方。這會使得程序分析和優化技術更加可行:

快速查找JDK和應用程式的類;及早進行字節碼的檢驗;積極級聯(aggressive inlining)像lambda表達式這樣的內容以及其他的編譯器優化;構建特定於JVM的內存鏡像,它加載時能夠比類文件更加高效;預先將方法體編譯為原生代碼;移除沒有用到的域、方法和類。——Jigsaw項目: 目標 & 需求(草案3)

有一些被稱為全程序優化(whole-program optimization)的技術,在Java 9中至少會實現兩種這樣的技術。還有包含一個工具,使用這個工具能夠分析給定的一組模塊,並使用上述的優化技術,創建更加高性能的二進位鏡像。

註解

目前,要自動發現帶有註解的類(如Spring註解標註的配置類),需要掃描特定包下的所有類。這通常會在程序啟動的時候完成,這在相當程度上會減慢啟動的過程。

模塊將會提供一個API,允許調用者識別所有帶有給定註解的類。一種預期的方式是為這樣的類創建索引,這個索引會在模塊編譯的時候創建。

與已有的概念和工具集成

診斷工具(如棧跟蹤信息)將會進行更新,其中會包含模塊的信息。而且,它們還會集成到反射API中,這樣就能按照操作類的方式來使用它們,還會包含版本信息,這一信息可以進行反射,也可以在運行時重載

模塊的設計能夠讓我們在使用構建工具時「儘可能地減少麻煩(with a minimum of fuss)」。編譯之後的模塊能夠用在classpath中,也能作為一個模塊來使用,這樣的話,庫的開發人員就沒有必要為classpath應用和基於模塊的應用分別創建多個構件了。

與其他模塊系統的相互操作也進行了規劃,這其中最著名的也就是OSGi。

儘管模塊能夠對其他的模塊隱藏包,但是我們依然能夠對模塊包含的類和接口執行白盒測試

特定OS的包

模塊系統在設計時,始終考慮到了包管理器文件格式,「如RPM、Debian以及Solaris IPS」。開發人員不僅能夠使用已有的工具將一組模塊集合創建為特定OS的包,這些模塊還能調用按照相同機制安裝的其他模塊。

開發人員還能夠將組成應用的一組模塊打包為特定OS的包,「終端用戶能夠按照目標系統的通用做法,安裝和調用所打成的包」。基於上述的介紹,我們可以得知只有目標系統中不存在的模塊才必須要打包進來。

動態配置

正在運行中的應用能夠創建、運行並發布獨立的模塊配置。在這些配置中,可以包含開發者和平台模塊。對於容器類架構,這會非常有用,如IDE、應用伺服器或其他Java EE平台。

不兼容性

按照Java的慣例,這些變更在實現時,會強烈關注到向後的兼容性,所有標準和非廢棄的API及機制都能夠繼續使用。但是項目可能會依賴其他缺乏文檔的構造,這樣的話,在往Java 9遷移的時候,就需要一些額外的工作了。

內部API不可用了

藉助於強封裝,每個模塊能夠明確聲明哪些類型會作為其API的一部分。JDK將會使用這個特性來封裝所有的內部API,因此它們會變得不可用了。

在Java 9所帶來的不兼容性中,這可能是涵蓋範圍最大的一部分。但是這也是最明顯的,因為它會導致編譯錯誤。

那麼,什麼是內部API呢?毫無疑問,位於sun.*包中的所有內容。如果位於包中,或者使用了@jdk.Exported註解,在Oracle JDK中它依然是可用的,如果沒有註解的話,那麼它就是不可用的了。能產生特殊問題的一個樣例就是sun.misc.Unsafe類。它用在了很多項目中,用來實現關鍵任務或性能要求較高的代碼,它將來可能不可用引發了很多相關討論。不過,在一次相關的交流中曾經提出,通過一個廢棄的命令行標記,它依然是可用的。考慮到無法將其所有的功能都放到公開API中,這可能是一種必要的權衡。另外一個樣例是com.sun.javafx.*包中的所有內容。這些類對於構建JavaFX控制項是至關重要的,並且它們還有一定數量的bug要修改。這些類中的大多數功能都會作為發布的目標

合併JDK和JRE

在具有可擴展的Java運行時之後,它允許我們很靈活地創建運行時鏡像,JDK和JRE就喪失了其獨有的特性,它們只是模塊組合中的兩種形式而已。

這意味著,這兩個構件將會具有相同的結構,包括目錄結構也相同,任何依賴它(如在原來的JDK目錄中會有名為jre的子目錄)的代碼就不能正常運行了。

lib/rt.jarlib/tools.jar這樣的內部JAR將不可用了。它們的內容將會存儲到特定實現的文件中,這些文件的格式還未明確說明,有可能會發生變化。

任何假設這些文件存在的代碼將無法正確運行。這可能對IDE或其他嚴重依賴這些文件的工具帶來一些切換的麻煩。

針對運行時鏡像內容的新URL模式

在運行時,有些API會返回針對類和資源文件的URL(如ClassLoader.getSystemResource)。在Java 9之前,它們都是jar URL,格式如下:

jar:file:<path-to-jar>!<path-to-file-in-jar>

Jigsaw項目將會使用模塊作為代碼文件的容器,單個JAR將不可用了。這需要一個新的格式,所以這些API將會返回jrt URL

jrt:/<module-name>/<path-to-file-in-module>

如果使用這些API所返回的實例來訪問文件的代碼(如URL.getContent),那麼運行方式會和現在一樣。但是,如果依賴於jar URL的結構(比如手動構建它們或對其進行解析),那麼就會出錯了。

移除授權標準重載機制

有一些Java API被稱為「獨立技術(Standalone Technology)」,它們的創建是在Java Community Process(如JAXB)之外的。對它們來說,有可能會升級其依賴或使用替代實現。授權標準重載機制允許在JDK中安裝這些標準的替代版本。

這種機制在Java 8中已經廢棄了,在Java 9中將會移除,會由上文所述的可升級模塊來替代。

移除擴展機制

藉助擴展機制,自定義API能夠被JDK中運行的所有應用程式使用,而不必在classpath中對其進行命名。

這種機制在Java 8中已經廢棄了,在Java 9中將會移除。有些本身有用的特性將會保留。

接下來要做什麼?

我們已經簡要了解了Jigsaw項目的歷史,看到是什麼在驅動它的發展並討論了它的目標,如何通過一些特性來實現這些目標。除了等待Java 9以外,我們還能做些什麼呢?

準備

我們應該為自己的項目做一些準備工作,檢查它們是否依賴Java 9中將要移除的內容。

至少,在檢查內部API依賴方面不再需要手動搜索了。從Java 8開始,JDK包含了Java依賴分析工具(Java Dependency Analysis Tool),名為JDeps介紹了一些內部的包,官方有針對Windows以及Unix的文檔),它能夠列出某個項目依賴的所有的包。如果在運行時使用-jdkinternals參數的話,那麼它將會列出該項目所使用的幾乎所有的內部API。

之所以說「幾乎所有」是因為它還無法識別Java 9中不可用的所有的包。這至少會影響到JavaFX所屬的包,可以查看JDK-8077349。(通過使用這個搜索,除了缺失的功能以外,我沒能發現其他的缺陷。)

至少存在三個用於Maven的JDeps插件:分別由ApachePhilippe Marschall以及我本人所提供。就目前來講,最後一個是唯一當jdeps-jdkinternals報告中依賴內部API時,導致構建失敗的插件。(現在,Apache的插件在出現內部API依賴時,也會提示構建失敗,參見InfoQ的這篇新聞。——譯者注)

討論

Jigsaw項目最新的消息來源於Jigsaw-Dev郵件列表。我也會在博客中繼續討論這個話題。

如果你擔心某個特定的API在Java 9中不可用的話,那麼你可以查看相關OpenJDK項目的郵件列表,因為他們會負責開發公開的版本。

採用

Java 9的早期試用構建版本已經可用了。不過,JSR 376依然處於開發階段,在這些構建版本中尚無法使用模塊系統,還會有很多的變化。(在目前的試用版中,已經包含了Jigsaw,不過最新的消息是Java 9又要延期六個月發布了。——譯者注)實際上,除了強封裝以外,其他的功能都已經就緒了。

將收集到的消息發送給Jigsaw-Dev郵件列表能夠反饋給項目。最後,引用JEP 220(臨近)結尾的一段話:

我們不可能抽象地確定這些變更的全部影響,所以必須要依賴廣泛的內部測試,尤其重要的還有外部測試。[……]如果有些變更會給開發人員、部署人員或終端用戶帶來難以承受的負擔,那麼我們將會研究減少其影響的方式。

另外,還有一個全球的Java用戶群組AdoptOpenJDK,它能夠很好地將早期試用者聯繫起來。

關於作者Nicolai Parlog是一名軟體開發人員,對Java充滿熱情。他不斷地閱讀、思考以及撰寫與Java相關的內容,他靠編碼為生,也以此為樂。他是多個開源項目的長期貢獻者,並在CodeFX上用博客記錄軟體開發相關的內容。你可以在Twitter上關注Nicolai。您好,朋友!您需要註冊一個InfoQ帳號或者登錄才能進行評論。在您完成註冊後還需要進行一些設置。

獲得來自InfoQ的更多體驗。

告訴我們您的想法

您可能感興趣
免責聲明:本文內容來源于InfoQ中文站,文章觀點不代表壹讀立場,如若侵犯到您的權益,或涉不實謠言,敬請向我們提出檢舉
最新文章 / 服務條款 / 私隱保護 / DMCA / 聯絡我們

壹讀/READ01.COM