Java平臺,標準版
Oracle JDK遷移指南
第11版
E94894-01
2018年9月
入門
本指南的目的是幫助您識別潛在問題,并在將現有Java應用程序遷移到最新JDK版本時為您提供有關如何繼續的建議。該指南還強調了對最新版本所做的重大更改和增強。
本指南包含以下部分:
JDK 11發布的重大變化
在將應用程序遷移到JDK 11之前,您應該了解它與JDK 10版本之間的更新和更改。如果要從JDK 8遷移,則還應熟悉從JDK 8遷移到以后的JDK版本中描述的JDK 8和更高版本之間的差異。
以下是JDK 11中的一些重要更改:
Oracle不再提供JRE和Server JRE下載; 因此,自動更新不再可用。
Oracle不再提供32位Windows下載。
JDK中不提供Java Web Start,Java插件和Java控制面板。請參閱刪除部署堆棧。
JDK中不再包含JavaFX。它現在可以從https://openjfx.io/單獨下載。
JAXB和JAX-WS不再與JDK捆綁在一起。請參閱刪除Java EE和CORBA模塊。
此外,還需要了解與安全相關的更新以及很少刪除的工具和組件。看到:
刪除部署堆棧
Java部署技術在JDK 9中已棄用,在JDK 11中已刪除。
Java applet和Web Start功能,包括Java插件,Java Applet Viewer,Java控制面板和Java Web Start,以及javaws
工具,已在JDK 11中刪除。
請參閱 刪除Java部署技術。
刪除Java EE和CORBA模塊
在JDK 11中,刪除了Java EE和CORBA模塊。不推薦在JDK 9中刪除這些模塊。
刪除的模塊是:
- java.xml.ws:用于XML Web服務的Java API(JAX-WS),用于Java平臺的Web服務元數據以及用于Java的附件的SOAP(SAAJ)
- java.xml.bind:用于XML綁定的Java體系結構(JAXB)
- java.xml.ws.annotation:Java SE定義的JSR-250 Common Annotations的子集,用于支持Web服務
- java.corba:CORBA
- java.transaction:Java SE定義的Java Transaction API的子集,用于支持CORBA對象事務服務
- java.activation:JavaBeans Activation Framework
- java.se.ee:上面六個模塊的聚合器模塊
- jdk.xml.ws:JAX-WS的工具
- jdk.xml.bind:JAXB的工具
如果不更改構建,則不會編譯引用這些API中的類的現有代碼。同樣,在這些API類的引用的類路徑上的代碼將失敗,NoDefClassFoundError
或者ClassNotFoundException
,除非改變了應用程序的部署制成。
請參閱JEP 320:刪除Java EE和CORBA模塊以獲取有關模塊可能替換的更多信息。
注意:
您可以從Maven下載JAXB和JAX-WS。
安全更新
JDK 11版本包括傳輸層安全性(TLS)1.3規范(RFC 8446)的實現。
TLS 1.3是傳輸層安全性(TLS)協議的最新版本(2018年8月),默認情況下在JDK 11中啟用。此版本不僅關注速度改進,還通過強調現代加密技術來更新協議的整體安全性。實踐,并禁止過時或弱的加密算法。(例如,不再允許RSA密鑰交換和普通DSA簽名。)
TLS 1.3協議中添加了一些功能以提高向后兼容性,但有幾個問題需要注意。有關詳細信息,請參閱JEP 332。
刪除安全證書
已從JDK 11中的信任庫中刪除以下根證書:
使用已刪除證書的產品可能不再有效。如果需要這些證書,則必須使用缺少的證書配置和填充cacerts。為了證書添加到信任,看到密鑰工具在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>指南。
刪除了API,工具和組件
本節提供有關在JDK 11中刪除的API,工具和組件的詳細信息。
在JDK 11中刪除了API
在JDK 11中刪除了以下API。許多這些API在以前的版本中已被棄用,并且已被更新的API替換。有關可能的替代方案的信息,請參閱JDK 11 API規范。
javax.security.auth.Policy
java.lang.Runtime.runFinalizersOnExit(boolean)
java.lang.SecurityManager.checkAwtEventQueueAccess()
java.lang.SecurityManager.checkMemberAccess(java.lang.Class,int)
java.lang.SecurityManager.checkSystemClipboardAccess()
java.lang.SecurityManager.checkTopLevelWindow(java.lang.Object)
java.lang.System.runFinalizersOnExit(boolean)
java.lang.Thread.destroy()
java.lang.Thread.stop(java.lang.Throwable)
JDK 11未提供的工具和組件
以下是JDK 11未附帶的工具和組件列表。
主要工具
appletviewer
請參閱JDK-8200146:刪除appletviewer啟動器。
CORBA工具
idlj
orbd
servertool
tnamesrv
此外,rmic
(RMI編譯器)將不再支持-idl
或-iiop
選項。請參閱 JDK 11發行說明。
Java Web服務工具
schemagen
wsgen
wsimport
xjc
Java部署工具
javapackager
javaws
注意:
pack 200
并且unpack200
已被棄用,可能會在將來的JDK版本中刪除。
請參閱從JDK和JEP中刪除JavaFX 336:棄用Pack200工具和API。
監控工具
-
jmc
:在JDK 11中,JMC作為獨立程序包提供,而不是捆綁在JDK中。
請參閱從JDK和Java Mission Control中刪除JMC。
JVM管理-MIB.mib中
JVM-MANAGEMENT-MIB.mib
已刪除通過SNMP進行JVM監視和管理的規范。請參閱刪除JVM-MANAGEMENT-MIB.mib。
SNMP代理
該 jdk.snmp
模塊已被刪除。請參閱刪除SNMP代理。
Oracle桌面特定刪除
- Oracle JDK T2K字體光柵器已被刪除。
- Lucida字體:Oracle JDK不再提供任何字體,完全依賴于操作系統上安裝的字體。請參閱從Oracle JDK中刪除Lucida字體。
準備遷移
以下部分將幫助您成功遷移您的應用程序:
下載最新的JDK
下載并安裝最新的JDK版本。
在重新編譯之前運行程序
嘗試在最新的JDK版本(JDK 11)上運行您的應用程序。大多數代碼和庫應該在JDK 11上運行而不做任何更改,但可能有一些庫需要升級。
注意:
遷移是一個迭代過程。您可能會發現最好首先嘗試運行您的程序(此任務),然后或多或少地并行完成這三項任務:
運行應用程序時,請從JVM中查找有關過時VM選項的警告。如果VM無法啟動,請查找已刪除的GC選項。
如果您的應用程序成功啟動,請仔細查看您的測試并確保其行為與您使用的JDK版本相同。例如,一些早期采用者注意到他們的日期和貨幣格式不同。請參閱默認使用CLDR區域設置數據。
要使代碼適用于最新的JDK版本,請了解每個JDK版本中的新功能和更改。
有關JDK 11中的新功能和更改的詳細信息,請參閱JDK 11中的新增功能 - 新增功能和增強功能。
有關新功能和更改JDK 10的詳細信息,請參閱什么在JDK 10的新功能。
-
對于所有的JDK 9的新功能的完整列表,請參閱什么在JDK 9的新功能。
有關JDK 9中的更改的詳細信息,請參閱JDK 9發行說明。
即使您的程序似乎成功運行,您也應該完成本指南中的其余步驟并查看問題列表。
更新第三方庫
對于您使用的每個工具和第三方庫,您可能需要具有支持最新JDK版本的更新版本。
檢查第三方庫和工具供應商的網站,以獲取適用于最新JDK的每個庫或工具的版本。如果存在,則下載并安裝新版本。
如果使用Maven或Gradle構建應用程序,請確保升級到支持最新JDK版本的更新版本。
如果使用IDE開發應用程序,則可能有助于遷移現有代碼。NetBeans,Eclipse和IntelliJ IDE都有可用的版本,包括對最新JDK的支持。
您可以在OpenJDK wiki上的Quality Outreach上看到OpenJDK 構建的許多免費開源軟件(FOSS)項目的測試狀態。
如果需要,編譯您的應用程序
使用最新的JDK編譯器編譯代碼將簡化向未來版本的遷移,因為代碼可能依賴于已被確定為有問題的API和功能。但是,并非絕對必要。
如果需要使用JDK 11編譯器編譯代碼,請注意以下事項:
-
如果在源代碼中使用下劃線字符(“_”)作為單字符標識符,則代碼將無法在JDK 11中編譯。它在JDK 8中生成警告,并從JDK 9開始生成錯誤。
舉個例子:
static Object _ = new Object();
此代碼從編譯器生成以下錯誤消息:
MyClass.java:2: error: as of release 9, '_' is a keyword, and may not be used as a legal identifier.
-
如果使用
-source
和-target
選項javac
,則檢查您使用的值。支持的
-source/-target
值為11(默認值),10,9,8,7和6(不推薦使用6,并且在使用此值時會顯示警告)。在JDK 8,
-source
和-target
1.5 / 5的值和更早被棄用,并引起了警告。在JDK 9及更高版本中,這些值會導致錯誤。>javac -source 5 -target 5 Sample.java warning: [options] bootstrap class path not set in conjunction with -source 5 error: Source option 5 is no longer supported. Use 6 or later. error: Target option 1.5 is no longer supported. Use 1.6 or later.
如果可能,請使用新
--release
標志而不是-source
和-target
選項。見javac
在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>。該
--release
標志的有效參數遵循與之相同的策略,-source
并且-target
一加三后退。它
javac
可以識別和處理所有以前的JDK的類文件,一直回到JDK 1.0.2類文件。 -
在JDK 11中仍然可以訪問關鍵的內部JDK API,例如sun.misc.Unsafe,但是在編譯時無法訪問大多數JDK的內部API。您可能會收到編譯錯誤,指出您的應用程序或其庫依賴于內部API。
要標識依賴項,請運行Java依賴關系分析工具。請參閱在您的代碼上運行jdeps。如果可能,請更新代碼以使用支持的替換API。
您可以使用該
--add-exports
選項作為臨時解決方法來編譯源代碼,并引用JDK內部類。 您可能會看到比以前更多的棄用警告。
在您的代碼上運行jdeps
jdeps
在應用程序上運行該工具,以查看應用程序和庫所依賴的包和類。如果您使用內部API,則jdeps
可以建議替換以幫助您更新代碼。
要查找內部JDK API的依賴項,請jdeps
使用該-jdkinternals
選項運行。例如,如果您jdeps
在調用的類上運行sun.misc.BASE64Encoder
,您將看到:
>jdeps -jdkinternals Sample.class
Sample.class -> JDK removed internal API
Sample -> sun.misc.BASE64Encoder JDK internal API (JDK removed internal API)
Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependency on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8
如果您使用Maven,則可以使用jdeps
插件。
對于jdeps
語法,請參見jdeps
在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>。
請記住,這jdeps
是一個靜態分析工具,代碼的靜態分析可能無法提供完整的依賴項列表。如果代碼使用反射來調用內部API,則jdeps
不會警告您。
從JDK 8遷移到以后的JDK版本
JDK 8和后來的JDK版本之間發生了重大變化。
每個新的Java SE版本都會引入一些二進制,源代碼和行為不兼容的版本。在JDK 9中發生的Java SE平臺的模塊化帶來了許多好處,但也帶來了許多變化。僅使用官方Java SE平臺API和受支持的JDK特定API的代碼應繼續無變化地工作。使用JDK內部API的代碼應繼續運行,但應遷移以使用支持的API。
以下部分描述了在將JDK 8應用程序遷移到以后的JDK版本時應注意的JDK包和API中的更改。
查看運行應用程序時可能遇到的更改列表。
當您的應用程序在最新版本的JDK上成功運行時,請查看后續步驟,這將幫助您避免將來的版本出現問題。
了解運行時訪問警告
某些工具和庫使用反射來訪問僅供內部使用的JDK部分。在將來的JDK版本中將禁用此非法反射訪問。目前,默認情況下允許并發出警告。
例如,以下是啟動Jython時發出的警告:
>java -jar jython-standalone-2.7.0.jar
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper (file:/C:/Jython/jython2.7.0/jython-standalone-2.7.0.jar) to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11)
如果您看到這樣的警告,請聯系工具或庫的維護人員。警告的第二行命名精確的JAR文件,其代碼使用反射來訪問JDK的內部部分。
默認情況下,在java
啟動程序啟動的進程的生命周期中,最多會發出一條有關反射訪問的警告。警告的確切時間取決于執行反射訪問操作的工具和庫的行為。警告可能會在過程的生命周期的早期出現,也可能在啟動后很長時間出現。
您可以使用--add-opens
命令行標志在逐個庫的基礎上禁用警告消息。例如,您可以通過以下方式啟動Jython:
>java --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED -jar jython-standalone-2.7.0.jar
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11)
這次,不發出警告,因為java
調用明確地確認了反射訪問。如您所見,您可能需要指定多個--add-opens
標志來覆蓋類路徑上的庫嘗試的所有反射訪問操作。
要更好地理解工具和庫的行為,可以使用命令行標志。該標志導致為每個非法反射訪問操作發出警告消息。此外,您還可以通過設置獲取有關非法反射訪問操作的詳細信息,包括堆棧跟蹤。 --illegal-access=warn``--illegal-access=debug
如果您更新了庫,或者獲得了庫,那么您可以嘗試使用命令行標志。除了由其他命令行選項啟用的操作外,它禁用所有反射訪問操作,例如。這將是未來版本中的默認模式。 --illegal-access=deny``--add-opens
有兩個選項可以讓您以特定方式打破封裝。您可以結合使用它們,或者如前所述,來抑制警告。 --illegal-access=deny
- 如果需要使用已無法訪問的內部API,請使用
--add-exports
runtime選項。您還可以--add-exports
在編譯時使用來訪問內部API。 - 如果必須允許類路徑上的代碼進行深入反射以訪問非公共成員,請使用該
--add-opens
選項。
如果要禁止所有反射訪問警告,請在需要時使用--add-exports
和--add-opens
選項。
--add出口
如果必須使用默認情況下無法訪問的內部API,則可以使用--add-exports
命令行選項中斷封裝。
該--add-exports
選項的語法是:
--add-exports <source-module>/<package>=<target-module>(,<target-module>)*
其中<source-module>
和<target-module>
是模塊名稱,<package>
是包的名稱。
--add-exports
如果目標模塊讀取源模塊,則該選項允許目標模塊中的代碼訪問源模塊的命名包中的類型。
作為特殊情況,如果<target-module>
是ALL-UNNAMED
,則將源包導出到所有未命名的模塊,無論它們是最初存在還是稍后創建。例如:
--add-exports java.management/sun.management=ALL-UNNAMED
此示例允許所有未命名模塊中的代碼(類路徑上的代碼)訪問公共類型的公共成員java.management/sun.management
。如果類路徑上的代碼嘗試進行深度反射以訪問非公共成員,則代碼將失敗。
如果oldApp
在類路徑上運行的應用程序必須使用模塊的未導出com.sun.jmx.remote.internal
包java.management
,則可以通過以下方式授予其所需的訪問權限:
--add-exports java.management/com.sun.jmx.remote.internal=ALL-UNNAMED
您還可以使用JAR文件清單中斷封裝:
Add-Exports:java.management/sun.management
--add-exports
仔細使用該選項。您可以使用它來訪問庫模塊的內部API,甚至是JDK本身的內部API,但這樣做需要您自擔風險。如果該內部API發生更改或被刪除,則您的庫或應用程序將失敗。
另見JEP 261。
--add-打開
如果必須允許類路徑上的代碼進行深度反射以訪問非公共成員,請使用--add-opens
運行時選項。
有些圖書館深入反思,這意味著setAccessible(true)
他們可以訪問所有成員,包括私人成員。您可以使用命令行--add-opens
上的選項授予此訪問權限java
。使用此選項不會生成警告消息。
如果,您在運行時看到或發出消息,則可以使用運行時選項,將參數基于異常消息中顯示的信息。 --illegal-access=deny``IllegalAccessException``InaccessibleObjectException``--add-opens
語法--add-opens
是:
--add-opens module/package=target-module(,target-module)*
該選項允許<module>
開<package>
來<target-module>
,無論模塊聲明。
作為特殊情況,如果<target-module>
是ALL-UNNAMED
,則將源包導出到所有未命名的模塊,無論它們是最初存在還是稍后創建。例如:
--add-opens java.management/sun.management=ALL-UNNAMED
此示例允許類路徑上的所有代碼訪問java.management/sun.management
包中公共類型的非公共成員。
注意:
如果您正在使用JNI調用API(例如,包括Java Web Start JNLP文件),則必須在--add-opens
其值和其值之間包含等號。
<j2se version="10" java-vm-args="--add-opens=module/package=ALL-UNNAMED" />
--add-opens
在命令行上,其值和它的值之間的等號是可選的。
新版本 - 字符串方案
JDK 10引入了一些小的更改,以更好地適應基于時間的發布模型,以及JDK 9中引入的版本字符串方案.JDK 11保留了JDK 10中引入的版本字符串格式。
如果您的代碼依賴于版本字符串格式來區分主要版本,次要版本,安全版本和補丁更新版本,那么您可能需要更新它。
新版本字符串的格式為:
$FEATURE.$INTERIM.$UPDATE.$PATCH
添加了一個簡單的Java API來解析,驗證和比較版本字符串。請參閱java.lang.Runtime.Version。
見版本字符串格式的<cite style="box-sizing: border-box;">Java平臺,標準版安裝指南</cite>。
有關JDK 9中引入的版本字符串的更改,請參閱 JEP 223:新版本字符串方案。
有關JDK 10中引入的版本字符串更改,請參閱JEP 322:基于時間的發行版本控制。
對已安裝的JDK / JRE映像的更改
JDK和JRE已經發生了重大變化。
更改了JDK和JRE布局
安裝JDK之后,如果查看文件系統,您會注意到目錄布局與JDK 9之前的版本不同。
JDK 11
JDK 11沒有JRE映像。見JDK安裝目錄結構在<cite style="box-sizing: border-box;">Java平臺,標準版安裝指南</cite>。
JDK 9和JDK 10
早期版本生成了兩種類型的運行時映像:JRE,它是Java SE平臺的完整實現,以及JDK,它包括jre/
目錄中的整個JRE ,以及開發工具和庫。
在JDK 9和JDK 10中,JDK和JRE是兩種類型的模塊化運行時映像,其中每個映像都包含以下目錄:
bin
:包含二進制可執行文件。conf
:包含.properties
,.policy
和其他類型的文件,供開發人員,部署人員和最終用戶編輯。這些文件以前位于lib
目錄或其子目錄中。lib
:包含動態鏈接庫和JDK的完整內部實現。
在JDK 9和JDK 10中,仍然有單獨的JDK和JRE下載,但每個都具有相同的目錄結構。JDK映像包含歷史上在JDK中找到的額外工具和庫。沒有jdk/
與jre/
包裝目錄相對應,并且二進制文件(例如java
命令)不會重復。
請參閱JEP 220:模塊化運行時映像。
新的類加載器實現
JDK 9及更高版本維護自1.2版本以來存在的類加載器的層次結構。但是,已經進行了以下更改以實現模塊系統:
應用程序類加載器不再是URLClassLoader的實例,而是內部類的實例。它是模塊中類的默認加載器,既不是Java SE也不是JDK模塊。
-
擴展類加載器已重命名; 它現在是平臺類加載器。通過平臺類加載器可以保證Java SE Platform中的所有類都可見。此外,通過平臺類加載器可以保證在Java Community Process下標準化但不屬于Java SE Platform的模塊中的類。
僅僅因為通過平臺類加載器可見類并不意味著該類實際上是由平臺類加載器定義的。Java SE平臺中的某些類由平臺類加載器定義,而其他類則由引導類加載器定義。應用程序不應該依賴于哪個類加載器定義哪個平臺類。
在JDK 9中實現的更改可能會影響使用
null
(即引導類加載器)創建類加載器的代碼作為父類加載器,并假定所有平臺類對父級是可見的。可能需要更改此類代碼以使用平臺類加載器作為父代(請參閱ClassLoader.getPlatformClassLoader)。平臺類加載器不是URLClassLoader的實例,而是內部類的實例。
引導類加載器仍然是內置的Java虛擬機和代表
null
中ClassLoader的 API。它定義了一些關鍵模塊中的類,例如java.base。因此,它定義的類比JDK 8中的類少得多,因此使用-Xbootclasspath/a
或創建類加載器null
作為父級的應用程序可能需要如前所述進行更改。
刪除了JDK 9中的rt.jar和tools.jar
類和資源文件之前存儲在lib/rt.jar
,lib/tools.jar
,lib/dt.jar
和其他各種內部JAR文件都存儲在一個更有效的格式在實現特定的文件lib
目錄。
刪除rt.jar
和類似文件會導致以下方面的問題:
-
從JDK 9開始,ClassLoader.getSystemResource不返回指向JAR文件的URL(因為沒有JAR文件)。相反,它返回一個
jrt
URL,該URL命名存儲在運行時映像中的模塊,類和資源,而不會泄露圖像的內部結構或格式。例如:
ClassLoader.getSystemResource("java/lang/Class.class");
在JDK 8上運行時,此方法返回以下形式的JAR URL:
jar:file:/usr/local/jdk8/jre/lib/rt.jar!/java/lang/Class.class
嵌入文件URL以命名運行時映像中的實際JAR文件。
模塊化圖像不包含任何JAR文件,因此這種形式的URL毫無意義。在JDK 9及更高版本中,此方法返回:
jrt:/java.base/java/lang/Class.class
該java.security.CodeSource中的 API和安全策略文件所使用的網址來命名的將被授予特定權限的代碼庫的位置。請參閱策略文件語法在<cite style="box-sizing: border-box;">Java平臺,標準版安全開發人員指南</cite>。目前
conf/security/java.policy
,使用文件URL 在文件中標識了需要特定權限的運行時系統組件。較舊版本的IDE和其他開發工具需要能夠枚舉存儲在運行時映像中的類和資源文件,并通過打開和讀取
rt.jar
以及類似文件直接讀取其內容。模塊化圖像無法實現這一點。
在JDK 9中刪除了擴展機制
在JDK 8及更早版本中,擴展機制使運行時環境可以查找和加載擴展類,而無需在類路徑上特別命名它們。從JDK 9開始,如果需要使用擴展類,請確保JAR文件位于類路徑上。
在JDK 9和JDK 10中,如果設置了系統屬性,或者目錄存在,javac
編譯器和java
啟動器將退出。要另外檢查特定于平臺的系統范圍目錄,請指定命令行選項。如果目錄存在且不為空,則會導致出現相同的退出行為。擴展類加載器保留在JDK 9(及更高版本)中,并被指定為平臺類加載器(請參閱getPlatformClassLoader。)但是,在JDK 11中,此選項已過時,并在使用時發出警告。java.ext.dirs``lib/ext``-XX:+CheckEndorsedAndExtDirs
以下錯誤表示您的系統配置為使用擴展機制:
<JAVA_HOME>/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.
如果java.ext.dirs
設置了系統屬性,您將看到類似的錯誤。
要修復此錯誤,請刪除ext/
目錄或java.ext.dirs
系統屬性。
請參閱JEP 220:模塊化運行時映像。
刪除了背書標準覆蓋機制
該java.endorsed.dirs
系統屬性和lib/endorsed
目錄不再存在。如果檢測到任何一個,javac
編譯器和java
啟動器將退出。
從JDK 9開始,您可以使用可升級模塊或將JAR文件放在類路徑上。
此機制旨在供應用程序服務器覆蓋JDK中使用的組件。要更新的包將放入JAR文件中,系統屬性java.endorsed.dirs
將告訴Java運行時環境在哪里找到它們。如果未指定此屬性的值,則使用默認值$JAVA_HOME/lib/endorsed
。
在JDK 8中,您可以使用-XX:+CheckEndorsedAndExtDirs
命令行參數來檢查系統上任何位置的此類目錄。
在JDK 9及更高版本中,如果設置了系統屬性,或者目錄存在,javac
編譯器和java
啟動器將退出。java.endorsed.dirs``lib/endorsed
以下錯誤表示您的系統配置為使用支持的標準覆蓋機制:
<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs
in modular form will be supported via the concept of upgradeable modules.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
如果java.endorsed.dirs
設置了系統屬性,您將看到類似的錯誤。
要修復此錯誤,請刪除該lib/endorsed
目錄,或取消設置java.endorsed.dirs
系統屬性。
請參閱JEP 220:模塊化運行時映像。
Windows注冊表項更改
安裝JDK時,Java 11安裝程序會創建這些Windows注冊表項:
“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK”
“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\11”
如果安裝了兩個版本的JDK,則會創建兩個不同的Windows注冊表項。例如,如果JDK 11.0.1與JDK 11一起安裝,則安裝程序會創建另一個Windows注冊表項,如下所示:
“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK”
“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\11.0.1”
刪除或更改的API
本節重點介紹了在默認行為中無法訪問,刪除或更改的API。編譯或運行應用程序時,您可能會遇到本節中描述的問題。
請參閱JDK 11中的已刪除API。
刪除了JDK 9和JDK 10中的API
以下是從JDK 9和JDK 10發行版中刪除的一些重要API。
刪除了java。* API
Java團隊致力于向后兼容。如果應用程序在JDK 8中運行,那么它將在JDK 9及更高版本上運行,只要它使用受支持且供外部使用的API即可。
這些包括:
- JCP標準,java。,javax。
- JDK特定的API,一些com.sun。,一些jdk。
支持的API可以從JDK中刪除,但只能通知。通過運行靜態分析工具,了解您的代碼是否使用了棄用的API jdeprscan
。
java。*在JDK 9中刪除的API包括java.util.logging.LogManager和java.util.jar.Pack200包中以前棄用的方法:
java.util.logging.LogManager.addPropertyChangeListener
java.util.logging.LogManager.removePropertyChangeListener
java.util.jar.Pack200.Packer.addPropertyChangeListener
java.util.jar.Pack200.Packer.removePropertyChangeListener
java.util.jar.Pack200.Unpacker.addPropertyChangeListener
java.util.jar.Pack200.Unpacker.removePropertyChangeListener
刪除和將來刪除sun.misc和sun.reflect API
與java。* API不同,幾乎所有sun。* API都不受支持,JDK內部API,并且可能隨時消失。
在JDK 9中刪除了一些sun。* API。值得注意的是,sun.misc.BASE64Encoder和sun.misc.BASE64Decoder被刪除了。而是使用在JDK 8中添加的受支持的java.util.Base64類。
如果您使用這些API,則可能希望遷移到其支持的替換項:
-
sun.misc.Unsafe
通過使用變量句柄可以使用此類中的許多方法的功能,請參閱JEP 193:可變句柄。
-
sun.reflect.Reflection :: getCallerClass(INT)
相反,使用stack-walking API,請參閱JEP 259:Stack-Walking API。
java.awt.peer不可訪問
該java.awt.peer中和java.awt.dnd.peer包無法訪問,在JDK 9開始的包從來沒有在Java SE API的一部分,盡管是java中。*命名空間。
引用這些包中定義的類型的Java SE API中的所有方法都從JDK 9中刪除。調用先前接受或返回在這些包中定義的類型的方法的代碼不再編譯或運行。
java.awt.peer類有兩種常見用法。您應該按如下方式替換它們:
-
要查看是否已設置對等方:
if (component.getPeer() != null) { .. }
將其替換為JDK 1.1 API中的Component.isDisplayable():
public boolean isDisplayable() { return getPeer() != null;
-
要測試組件是否輕量級:
if (component.getPeer() instanceof LightweightPeer) ..
將其替換為JDK 1.2 API中的Component.isLightweight():
public boolean isLightweight() { return getPeer() instanceof LightweightPeer;
刪除了com.sun.image.codec.jpeg包
已刪除非標準包com.sun.image.codec.jpeg。請改用Java Image I / O API。
該的com.sun.image.codec.jpeg包JDK 1.2中加入作為控制裝載和JPEG格式的圖像文件的保存的一個非標準的方式。它從未成為平臺規范的一部分。
在JDK 1.4中,Java Image I / O API作為標準API添加,位于javax.imageio包中。它提供了一種標準機制,用于控制采樣圖像格式的加載和保存,并要求所有兼容的Java SE實現都支持基于Java Image I / O規范的JPEG。
刪除了壓縮配置文件的工具支持
從JDK 9開始,您可以選擇針對Java運行時映像中的任何模塊子集構建和運行應用程序,而無需依賴預定義的配置文件。
Java SE 8中引入的配置文件定義了Java SE Platform API的子集,這些子集可以減少存儲容量有限的設備上Java運行時的靜態大小。在JDK 8支持工具三個配置文件,compact1
,compact2
,和compact3
。有關每個配置文件的API組合,請參閱JDK 8文檔中的詳細配置文件組合和API參考。
在JDK 8中,您可以使用該-profile
選項在運行javac
和java
命令時指定配置文件。從JDK 9開始,該-profile
選項javac
僅與--release 8
選項一起支持,并且不受支持java
。
JDK 9及更高版本允許您選擇在編譯和運行時使用的模塊。通過使用新--limit-modules
選項指定模塊,您可以獲得緊湊配置文件中的相同API。該選項是由兩個支持javac
和java
命令,如在以下實施例:
javac --limit-modules java.base,java.logging MyApp.java
java --limit-modules java.base,java.logging MyApp
為Java SE 8中的每個配置文件指定的包將通過以下模塊集共同導出:
對于
compact1
配置文件:java.base,java.logging,java.scripting對于
compact2
配置文件:java.base,java.logging,java.scripting,java.rmi,java.sql,java.xml對于
compact3
配置文件:java.base,java.logging,java.scripting,java.rmi,java.sql,java.xml,java.compiler,java.instrument,java.management,java.naming,java.prefs,java。 security.jgss,java.security.sasl,java.sql.rowset,java.xml.crypto
您可以使用該jdeps
工具對源代碼中使用的Java包進行靜態分析。這為您提供了執行應用程序所需的一組模塊。compact3
例如,如果您一直在使用該配置文件,那么您可能會發現在構建應用程序時不需要包含整套模塊。見jdeps
在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>。
請參閱JEP 200:模塊化JDK。
默認情況下使用CLDR區域設置數據
從JDK 9開始,Unicode Consortium的公共區域設置數據存儲庫(CLDR)數據作為默認區域設置數據啟用,因此您可以使用標準區域設置數據而無需任何進一步操作。
在JDK 8中,雖然CLDR區域設置數據與JRE捆綁在一起,但默認情況下不啟用它。
使用區域設置敏感服務(如日期,時間和數字格式)的代碼可能會使用CLDR區域設置數據生成不同的結果。請記住,即使System.out.printf()也是區域設置感知的。
要啟用與JDK 8兼容的行為,請將系統屬性設置為例如前面的java.locale.providers
值。COMPAT``CLDR``java.locale.providers=COMPAT,CLDR
見CLDR語言環境數據通過默認啟用的<cite style="box-sizing: border-box;">Java平臺,標準版國際指南</cite>和JEP 252:使用CLDR語言環境數據的默認。
部署
Java部署技術在JDK 9中已棄用,在JDK 11中已刪除。
使用jlink
JDK 9引入的工具打包和部署專用運行時,而不是依賴于預安裝的系統JRE。
刪除了啟動時JRE版本選擇
從JDK 9開始,刪除了請求從發布時啟動的JRE版本的JRE版本的能力。
現代應用程序通常使用Java Web Start(JNLP),本機OS打包系統或活動安裝程序進行部署。這些技術有自己的方法來管理所需的JRE,根據需要查找或下載并更新所需的JRE。這使得啟動程序的啟動時JRE版本選擇已過時。
在以前的版本中,您可以指定啟動應用程序時要使用的JRE版本(或版本范圍)。通過命令行選項和應用程序的JAR文件中的清單條目,可以選擇版本。
從JDK 9開始,java
啟動器修改如下:
- 如果
-version:
在命令行上給出了該選項,則發出錯誤消息并退出。 - 如果
JRE-Version
在JAR文件中找到清單條目,則發出警告消息并繼續。
刪除了對序列化小程序的支持
從JDK 9開始,不支持將applet部署為序列化對象的能力。借助現代壓縮和JVM性能,以這種方式部署applet沒有任何好處。
在object
該屬性applet
標簽和object
和java object
applet的參數標簽啟動小程序時被忽略。
而不是序列化applet,使用標準部署策略。
JNLP規范更新
JNLP(Java網絡啟動協議)已更新,以消除不一致性,使代碼維護更容易,并增強安全性。
JNLP已更新如下:
-
&
而不是&
在JNLP文件中。JNLP文件語法符合XML規范,所有JNLP文件都應該能夠由標準XML解析器解析。
JNLP文件允許您指定復雜的比較。以前,這是通過使用ampersand(
&
)完成的,但標準XML不支持此功能。如果您正在使用&
創建復雜的比較,請&
在JNLP文件中替換它。&
與所有版本的JNLP兼容。 -
將數字版本元素類型與非數字版本元素類型進行比較。
以前,當將
int
版本元素與另一個無法解析為int
的版本元素進行比較時,版本元素按字典順序通過ASCII值進行比較。從JDK 9開始,如果可以解析為
int
a 的元素是比其他元素更短的字符串,則在按字典順序按ASCII值進行比較之前,將使用前導零填充該元素。這確保不存在圓形。在使用版本比較和JNLP servlet的情況下,您應該僅使用數值來表示版本。
-
在
java
(或j2se
)元素中具有嵌套資源的組件擴展。這在規范中是允許的。它以前得到了支持,但這種支持沒有反映在規范中。
-
FX XML擴展。
該JNLP規范已經增強,一個添加
type
屬性application-desc
元素,并添加子元素param
中application-desc
(因為它已經是applet-desc
)。這不會導致現有應用程序出現問題,因為仍然支持以前指定JavaFX應用程序的方法。
請參閱JSR-056上的JNLP規范更新。
JDK 9中的安全更新
從JDK 9開始,一些與安全相關的默認值已更改。
JCE管轄權政策文件默認為無限制
如果您的應用程序以前需要Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files,那么您不再需要下載或安裝它們。它們包含在JDK中,默認情況下處于激活狀態。
如果您的國家/地區或用途需要更嚴格的策略,則仍然可以使用有限的Java加密策略文件。
如果默認情況下提供的任一策略文件都不滿足要求,則可以自定義這些策略文件以滿足您的需求。
請參閱文件中的crypto.policy
Security屬性<java-home>/conf/security/java.security
,或<cite style="box-sizing: border-box;">Java Platform,Standard Edition Security Developer's Guide</cite>中的Cryptographic Strength Configuration。
建議您咨詢您的出口/進口控制律師或律師以確定具體要求。
創建PKCS12密鑰庫
我們建議您為密鑰庫使用PKCS12格式。此格式是默認密鑰庫類型,基于RSA PKCS12個人信息交換語法標準。
請參閱創建密鑰庫與JSSE使用的<cite style="box-sizing: border-box;">Java平臺,標準版安全開發人員指南</cite>和密鑰工具在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>。
垃圾收集的變化
本節介紹從JDK 9開始的垃圾回收更改。
使G1成為默認垃圾收集器
Garbage-First垃圾收集器(G1 GC)是JDK 9及更高版本中的默認垃圾收集器。
對于大多數用戶而言,低暫停收集器(如G1 GC)應該提供比面向吞吐量的收集器更好的整體體驗,例如Parallel GC,它是JDK 8的默認值。
見為G1 GC人體工學默認值和可調默認的<cite style="box-sizing: border-box;">Java平臺,標準版Java虛擬機指南</cite>有關調整G1 GC的更多信息。
刪除了GC選項
以下GC組合將導致您的應用程序無法在JDK 9及更高版本中啟動:
DefNew + CMS
ParNew + SerialOld
Incremental CMS
CMS的前臺模式也已刪除。被刪除的命令行標志-Xincgc
,-XX:+CMSIncrementalMode
,-XX:+UseCMSCompactAtFullCollection
,-XX:+CMSFullGCsBeforeCompaction
,和-XX:+UseCMSCollectionPassing
。
命令行標志-XX:+UseParNewGC
不再有效。該ParNew
標志只能用于CMS和CMS要求ParNew
。因此,該-XX:+UseParNewGC
標志已被棄用,并且有資格在將來的版本中刪除。
請參閱JEP 214:刪除JDK 8中不推薦使用的GC組合。
刪除了永久代
在JDK 8中刪除了永久代,并且相關的VM選項會導致打印警告。您應該從腳本中刪除這些選項:
-XX:MaxPermSize=size
-XX:PermSize=size
在JDK 9及更高版本中,JVM會顯示如下警告:
Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0
知道永久代的工具可能必須更新。
請參閱JEP 122:刪除永久生成和JDK 9發行說明 - 已刪除的API,功能和選項。
GC日志輸出的更改
垃圾收集(GC)日志記錄使用JVM統一日志記錄框架,新舊日志之間存在一些差異。您正在使用的任何GC日志解析器可能都需要更改。
您可能還需要更新JVM日志記錄選項。所有與GC相關的日志記錄都應使用gc
標記(例如—Xlog:gc
),通常與其他標記結合使用。這些—XX:+PrintGCDetails
和-XX:+PrintGC
選項已被棄用。
請參閱啟用與JVM統一日志框架記錄在<cite style="box-sizing: border-box;">Java平臺,標準版工具參考</cite>和JEP 271:統一GC日志記錄。
刪除了工具和組件
此列表包括不再與JDK捆綁在一起的工具和組件。
要了解有關JDK 11中刪除的工具和組件的更多信息,請參閱JDK 11中的已刪除API。
刪除了Native-Header生成工具(javah)
該javah
工具已被優越的功能所取代javac
。它已在JDK 10中刪除。
從JDK 8開始,javac
提供了在編譯Java源代碼時編寫本機頭文件的功能,從而無需單獨的工具。
而不是javah
,使用
javac -h
刪除了JavaDB
JavaDB是Apache Derby的品牌重塑,不再包含在JDK中。
JavaDB與JDK 7和JDK 8捆綁在一起。它db
位于JDK安裝目錄的目錄中。
您可以從Apache Derby Downloads下載并安裝Apache Derby 。
刪除了JVM TI hprof代理
該hprof
代理程序庫已被刪除。
該hprof
劑被寫為演示代碼JVM工具界面,并沒有打算成為一個生產工具。hprof
代理的有用功能已被更好的替代方案所取代,包括JDK中包含的一些替代方案。
要以hprof
格式創建堆轉儲,請使用診斷命令(jcmd
)或jmap
工具:
對于CPU分析器功能,請使用與JDK捆綁在一起的Java Flight Recorder。
注意:
Java Flight Recorder需要商業許可才能用于生產。要了解有關商業功能以及如何啟用它們的更多信息,請訪問http://www.oracle.com/technetwork/java/javaseproducts/。
刪除了jhat工具
該jhat
工具是JDK 6中添加的實驗性,不受支持的堆可視化工具。高級堆可視化器和分析器已經可用多年。
刪除了java-rmi.exe和java-rmi.cgi啟動器
java-rmi.exe
來自Windows以及java-rmi.cgi
Linux和Solaris 的啟動程序已被刪除。
java-rmi.cgi
在$JAVA_HOME/bin
Linux和Solaris上。
java-rmi.exe
在$JAVA_HOME/bin
Windows上。
這些啟動程序被添加到JDK中以便于使用RMI CGI代理機制,該機制在JDK 8中已棄用。
幾年來,使用servlet代替RMI over HTTP的替代方案已經可用,甚至是首選。請參閱Java RMI和對象序列化。
從JMX RMIConnector中刪除了對IIOP傳輸的支持
來自JMX RMI連接器的IIOP傳輸支持及其支持類已從JDK中刪除。
在JDK 8中,對IIOP傳輸的支持從必需降級到可選。這是多版本努力從JMX Remote API中刪除對IIOP傳輸的支持的第一步。在JDK 9中,完全刪除了對IIOP的支持。
公共API更改包括:
該
javax.management.remote.rmi.RMIIIOPServerImpl
班已棄用。在調用時,它的所有方法和構造函數都會拋出java.lang.UnsupportedOperationException
一條解釋性消息。不會生成兩個類,
org.omg.stub.javax.management.rmi._RMIConnection_Stub
和org.omg.stub.javax.management.rmi._RMIConnection_Tie
。
刪除了Windows 32位客戶端VM
Windows 32位客戶端VM不再可用。僅提供服務器VM。
JDK 8及更早版本為Windows 32位系統提供了客戶端JVM和服務器JVM。JDK 9及更高版本僅提供服務器JVM,該服務器JVM經過調整以最大化峰值運行速度。
刪除了Java VisualVM
Java VisualVM是一個工具,它提供有關在Java虛擬機上運行的代碼的信息。該jvisualvm
工具提供了JDK 6,JDK 7和JDK 8。
Java VisualVM不再與JDK捆綁在一起,但您可以從VisualVM開源項目站點獲取它。
刪除了native2ascii工具
該native2ascii
工具已從JDK中刪除。由于JDK 9及更高版本支持基于UTF-8的屬性資源包,因此不再需要將基于UTF-8的屬性資源包轉換為ISO-8859-1的轉換工具。
見UTF-8屬性文件中的<cite style="box-sizing: border-box;">Java平臺,標準版國際指南</cite>。
刪除了特定于macOS的功能
本節包括從JDK 9開始已刪除的特定于macOS的功能。
特定于平臺的桌面功能
本java.awt.Desktop
類包含了蘋果專用的API的替代品com.apple.eawt
和com.apple.eio
套餐。新API取代了macOS API,并且與平臺無關。
com.apple.eawt
和com.apple.eio
包中的API 是封裝的,因此您無法在JDK 9或更高版本中針對它們進行編譯。但是,它們在運行時仍可訪問,因此編譯為舊版本的現有代碼將繼續運行。最終,使用apple
和com.apple
包及其子包中的內部類的庫或應用程序 將需要遷移到新的API。
在com.apple.concurrent
與apple.applescript
包沒有任何替代刪除。
刪除了AppleScript引擎
AppleScript引擎是一個特定于平臺的javax.script實現,在JDK中沒有任何替換,已被刪除。
AppleScript引擎在最近的版本中幾乎無法使用。該功能僅適用于已在系統上具有Apple版本AppleScriptEngine.jar
文件的系統上的JDK 7或JDK 8 。
下一步
在JDK 11上運行應用程序之后,這里有一些建議可以幫助您從Java SE平臺中獲得最大收益:
如果需要,使用工具中的新
-–release
標志交叉編譯到平臺的舊版本javac
。利用IDE的建議,使用最新功能更新代碼。
通過運行靜態分析工具,了解您的代碼是否使用了棄用的API
jdeprscan
。正如本指南中已經提到的,API可以從JDK中刪除,但只能提前通知。熟悉多版本JAR文件等新功能(請參閱參考資料
jar
)。
文檔可訪問性
有關Oracle對可訪問性的承諾的信息,請訪問Oracle Accessibility Program網站http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc。
訪問Oracle支持
已購買支持的Oracle客戶可通過My Oracle Support獲得電子支持。有關詳細信息,請訪問http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info或訪問http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs如果您聽力受損。
Java平臺,標準版Oracle JDK遷移指南,版本11
E94894-01
版權所有?2017,2018,Oracle和/或其附屬公司。版權所有。
本指南將幫助您將應用程序從Oracle JDK 8遷移到Oracle JDK 10。
本軟件和相關文檔根據許可協議提供,其中包含對使用和披露的限制,并受知識產權法保護。除非您的許可協議中明確允許或法律允許,否則您不得以任何形式使用,復制,復制,翻譯,廣播,修改,許可,傳輸,分發,展示,執行,發布或展示任何部分,或以任何方式。除非法律要求互操作性,否則禁止對該軟件進行逆向工程,反匯編或反編譯。
此處包含的信息如有更改,恕不另行通知,并且不保證沒有錯誤。如果您發現任何錯誤,請以書面形式向我們報告。
如果這是交付給美國政府的軟件或相關文檔或代表美國政府許可的任何人,則以下通知適用:
美國政府最終用戶:根據適用的聯邦采購法規和代理機構,Oracle計劃,包括任何操作系統,集成軟件,安裝在硬件上的任何程序和/或文檔,都是“商業計算機軟件”。具體的補充規定。因此,程序的使用,復制,披露,修改和調整,包括任何操作系統,集成軟件,安裝在硬件上的任何程序和/或文檔,應受適用于程序的許可條款和許可限制的約束。 。沒有其他權利授予美國政府。
該軟件或硬件被開發用于各種信息管理應用中的一般用途。它不是為任何本質上危險的應用而開發或打算使用的,包括可能造成人身傷害風險的應用。如果您在危險應用程序中使用此軟件或硬件,則您應負責采取所有適當的故障安全,備份,冗余和其他措施,以確保其安全使用。Oracle Corporation及其附屬公司對因在危險應用中使用此軟件或硬件而造成的任何損害不承擔任何責任。
Oracle和Java是Oracle和/或其附屬公司的注冊商標。其他名稱可能是其各自所有者的商標。
Intel和Intel Xeon是Intel Corporation的商標或注冊商標。所有SPARC商標均經許可使用,是SPARC International,Inc。的商標或注冊商標.AMD,Opteron,AMD徽標和AMD Opteron徽標是Advanced Micro Devices的商標或注冊商標。UNIX是The Open Group的注冊商標。
該軟件或硬件和文檔可以提供對來自第三方的內容,產品和服務的訪問或信息。除非您與Oracle之間的適用協議另有規定,否則Oracle Corporation及其附屬公司不對第三方內容,產品和服務的任何形式的保證承擔任何責任,并且明確拒絕承擔任何形式的保證。Oracle Corporation及其附屬公司對由于您訪問或使用第三方內容,產品或服務而導致的任何損失,成本或損害不承擔任何責任,但您與Oracle之間的適用協議中規定的除外。
</article>