JDK 9 中一些需要提防的坑
JDK 9正處于 開發的最后階段 , 向著9月21號的發布目標沖刺。 Java 平臺模塊系統 的公開評審投票基本上被 一致通過 ,所以目前一切都可以回歸正常了。
你可在此處下載 OpenJDK 9 (嘗鮮版)。
最近我在寫一篇文章,題目是“ JDK 9 中的 55 個新特性”。在其中,我試圖把重點放在所有非 JPMS 內容上。這也表明 JDK 9 中有幾個改動的部分,可以讓人們了解到其與早期版本的兼容性。我注意到也有一些與之相關的問題出現在了 Stackoverflow 上。
這篇博客是我能夠找到的你在將應用程序遷移到 JDK 9 時所有可能需要進行改動的內容的總結。我不會在此處討論 JPMS 、非公共的封裝類、對反射訪問的影響等。本文是一系列不同問題的集合。這個集合只涉及一些你需要注意的其他事情。
3. JDK 版本字符串(JEP 223):老的定義 JDK 版本的方法相當混亂。例如,我們有 JDK 8u131 ,但是如果你運行 java -version ,你會得到 java version "1.8.0_131" 。為了從人類和應用程序角度簡化這個(定義版本的方法),現在的版本格式是 JDK $MAJOR.$MINOR.$SECURITY.$PATCH ,所以在 JDK9 上的 java -version 將返回 java version "9"(一旦發布最終的 release 版,我們獲取更新之后該版本號就會改動)。這里重要的是,如果你在代碼中使用 JVM 的版本字符串,并依賴于當前版本格式,那么在 JDK 9 中你必須進行代碼改動才能正確運行。
4. Thread.stop(Throwable) 現在會拋出一個 UnsupportedOperationException ,它之前并沒有拋出類似異常。由于其自身缺乏線程安全性,因此不推薦使用此方法。另一個不帶參數的 Thread.stop() 版本仍然可以使用,并且不會拋出異常(但仍然不推薦使用,并強烈建議不要使用此函數)
5. Java 網絡登錄協議(Java Network Launch Protocol ,JNLP)已更新,以支持嚴格的配置文件解析。現在使用的格式符合 XML 規范,要求“&”版本范圍連接器表示為“&”。配置解析目前是嚴格的,這意味著一些在舊版本的 Java 中可以使用的文件現在將會產生錯誤。 有關更多詳細信息,請參見 JSR 52維護頁面 。
6. 與 JPMS 相關的擴展機制(可選軟件包)和已批準的標準覆蓋機制都已被刪除,并使用 JPMS 對應物替代。因此,$JAVA_HOME/lib/ext 和 $JAVA_HOME/lib/endorsed 的目錄已被刪除。如果你重新創建這些目錄,并嘗試把東西放在這些目錄下,祈禱他們能工作,這是不可能的。JVM 在查找到這些目錄時將無法啟動,你將收到以下錯誤消息:
/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
7. 六個之前已棄用的公共方法已經被刪除。這是一件相當大的事情,因為這些是 Java 歷史上第一次要刪除的API。已刪除的方法包括java.util.jar.Pack200,java.util.jar.Unpack200中的addPropertyChangeListener()、removePropertyChangeListener(),以及 java.util.logging.LogManager類。
8.作為 Java Authentication and Authorization Service (JAAS,Java授權認證服務) 的一部分的 com.sun.security.auth.callback.DialogCallbackHandler 類已被刪除。它在 JDK 8 中就已被棄用。
9. JRE 版本選擇將不再可用。過去有兩種做法可以實現 JRE 版本選擇。第一個是在命令行中使用 -version: 選項。如果使用該選項,JVM 將中止而不再啟動。第二種方式是從 jar 文件的 manifest 。在這種情況下,JDK 9 將忽略該指令,但會正常啟動。有人覺得,與改變命令行相比,強迫人們改變 manifest 太麻煩了。請注意,-version 選項(不帶后面的冒號和版本號)仍然可以報告你所使用的 Java 運行時版本。
10. 廢棄的GC選項已被移除( JEP 214 )。 在 JDK 8( JEP 173 )中已經棄用了一些詳細的 GC 選項和選項組合。這些將不會被識別,并將導致 JVM 在啟動時中止。要注意的選項如下所示
-XX:-UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-Xincgc
-XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC -XX:-UseParNewGC
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSFullGCsBeforeCompaction
-XX:+UseCMSCollectionPassing
在 JDK 9 中,concurrent-mark-sweep (iCMS) 的增量模式已被移除,目前的計劃是在 JDK 10 中完全刪除 CMS 。
命令行選項
這對我來說似乎是一個很大的變化,但到目前為止,我還沒有看到它被突出強調過(或有良好的記錄文檔)。
除了上述 GC 選項之外,在 JVM 如何處理日志記錄中有重大改動。 JEP 158 引入了統一日志記錄系統,并且該系統被用在 GC 日志中,用于提供統一的 GC 日志記錄( JEP 271 )。這會影響許多常用的 GC 日志記錄命令行選項以及其他一些操作。
為了弄清楚發生了什么改動,我從 OpenJDK 源代碼(特別是 src/share/vm/runtime/globals.hpp 文件)中提取了相關的行。通過做 diff ,我能夠得到所有從 JDK 8 中刪除的 -XX 選項以及已添加到 JDK 9 中的所有 -XX 選項的列表。然后,我寫了一個腳本,使用一個簡單的應用程序依次查看使用在 JDK 8 中支持但在 JDK 9 中已刪除的選項的結果。
對 -XX 選項的更改可以分為三組:
已忽略的命令行選項
如果使用其中的一個,您將收到以下警告消息,但 JVM 將正常啟動。
Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option <Option>; support was removed in 9.0
-
AdaptiveSizePausePolicy (自適應大小暫停策略)
-
CodeCacheMinimumFreeSpace(代碼緩存最小空閑空間)
-
DefaultThreadPriority(默認線程優先級)
-
JNIDetachReleasesMonitors(JNI分離釋放監視器)
-
LazyBootClassLoader(惰性類啟動器)
-
NmethodSweepCheckInterval(N方法掃描檢查間隔)
-
NmethodSweepFraction(N方法掃描片段)
-
PrintOopAddress(打印OOP地址)
-
ReflectionWrapResolutionErrors(反射包裝處理錯誤)
-
StarvationMonitorInterval(饑餓監視間隔)
-
ThreadSafetyMargin(線程安全邊界)
-
UseAltSigs(使用alt信號)
-
UseBoundThreads(使用綁定線程)
-
UseCompilerSafepoints(使用編譯器安全點)
-
UseFastAccessorMethods(使用快速訪問方法)
-
UseFastEmptyMethods(使用快速空方法)
-
BackEdgeThreshold(后邊緣閾值)
-
PreInflateSpin(預浸旋轉)
已棄用的命令行選項
這些選項將在 JVM 啟動時觸發警告,或者告訴你 JVM 將使用哪個選項,或者告訴你應該使用哪個選項。其中大部分與統一的 GC 日志有關。
以下是兩個關于警告信息的示例:
warning][gc] -XX:+PrintGC is deprecated. Will use -Xlog:gc instead.
Java HotSpot(TM) 64-Bit Server VM warning: Option CreateMinidumpOnCrash was deprecated in version 9.0 and will likely be removed in a future release. Use option CreateCoredumpOnCrash instead.
下表給出了 JDK 8 中的命令行選項及其在 JDK 9 中對應的替換選項。
JDK 8 Option | JDK 9 Replacement |
PrintGC | -Xlog:gc |
PrintGCDetails | -Xlog:gc* |
CreateMinidumpOnCrash | CreateCoredumpOnCrash (suggestion) |
DefaultMaxRAMFraction | MaxRAMFraction (suggestion) |
TraceBiasedLocking | -Xlog:biasedlocking=info |
TraceClassLoadingPreorder | -Xlog:class+preorder=debug |
TraceClassResolution | -Xlog:class+resolve=debug |
TraceMonitorInflation | -Xlog:monitorinflation=debug |
TraceRedfineClasses | -Xlog:redefine+class*=info |
TraceSafepointCleanupTime | -Xlog:safepoint+cleanup=info |
TraceClassLoading | -Xlog:class+load=info |
TraceLoaderConstraints | -Xlog:class+loader+constraints=info |
ConvertSleepToYield | NONE |
來自:https://www.oschina.net/translate/jdk-9-pitfalls