JDK 8遷移到JDK 11版本指南


Java平台,標准版

Oracle JDK遷移指南,官方https://docs.oracle.com/en/java/javase/11/migrate/index.html

第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。為了證書添加到信任,看到密鑰工具在Java平台,標准版工具參考指南。

刪除了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

請參閱JEP 320:刪除Java EE和CORBA模塊

Java部署工具

  • javapackager
  • javaws

注意:

pack 200並且unpack200已被棄用,可能會在將來的JDK版本中刪除。

請參閱從JDKJEP中刪除JavaFX 336:棄用Pack200工具和API

監控工具

  • jmc:在JDK 11中,JMC作為獨立程序包提供,而不是捆綁在JDK中。

請參閱從JDKJava 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版本的更新版本。

檢查第三方庫和工具供應商的網站,以獲取適用於最新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-target1.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在Java平台,標准版工具參考。

    --release標志的有效參數遵循與之相同的策略,-source並且-target一加三后退。

    javac可以識別和處理所有以前的JDK的類文件,一直回到JDK 1.0.2類文件。

    請參閱JEP 182:退休javac -source和-target選項的政策

  • 在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在Java平台,標准版工具參考。

請記住,這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-exportsruntime選項。您還可以--add-exports在編譯時使用來訪問內部API。
  • 如果必須允許類路徑上的代碼進行深入反射以訪問非公共成員,請使用該--add-opens選項。

如果要禁止所有反射訪問警告,請在需要時使用--add-exports--add-opens選項。

--add-exports

如果必須使用默認情況下無法訪問的內部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.internaljava.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-opens

如果必須允許類路徑上的代碼進行深度反射以訪問非公共成員,請使用--add-opens運行時選項。

有些類庫有深入反射,這意味着setAccessible(true)他們可以訪問所有成員,包括私人成員。您可以在使用java命令行上加--add-opens選項授予此訪問權限。使用此選項不會生成警告消息。

如果設置 --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

版本字符串格式的Java平台,標准版安裝指南。

有關JDK 9中引入的版本字符串的更改,請參閱 JEP 223:新版本字符串方案

有關JDK 10中引入的版本字符串更改,請參閱JEP 322:基於時間的發行版本控制

對已安裝的JDK / JRE映像的更改

JDK和JRE已經發生了重大變化。

更改了JDK和JRE目錄結構

安裝JDK之后,如果查看文件系統,您會注意到目錄布局與JDK 9之前的版本不同。

JDK 11

JDK 11沒有JRE映像。見JDK安裝目錄結構在Java平台,標准版安裝指南。

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.jarlib/tools.jarlib/dt.jar和其他各種內部JAR文件都存儲在一個更有效的格式在實現特定的文件lib目錄。

刪除rt.jar和類似文件會導致以下方面的問題:

  • 從JDK 9開始,ClassLoader.getSystemResource不返回指向JAR文件的URL(因為沒有JAR文件)。相反,它返回一個jrtURL,該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和安全策略文件所使用的網址來命名的將被授予特定權限的代碼庫的位置。請參閱策略文件語法在Java平台,標准版安全開發人員指南。目前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:模塊化運行時映像

刪除了Endorsed標准覆蓋機制

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

請參閱JEP 260:封裝大多數內部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。

刪除了Compact Profiles 工具支持

從JDK 9開始,您可以選擇針對Java運行時映像中的任何模塊子集構建和運行應用程序,而無需依賴預定義的配置文件。

Java SE 8中引入的配置文件定義了Java SE Platform API的子集,這些子集可以減少存儲容量有限的設備上Java運行時的靜態大小。在JDK 8支持工具三個配置文件,compact1compact2,和compact3。有關每個配置文件的API組合,請參閱JDK 8文檔中的詳細配置文件組合API參考

在JDK 8中,您可以使用該-profile選項在運行javacjava命令時指定配置文件。從JDK 9開始,該-profile選項javac僅與--release 8選項一起支持,並且不受支持java

JDK 9及更高版本允許您選擇在編譯和運行時使用的模塊。通過使用新--limit-modules選項指定模塊,您可以獲得緊湊配置文件中的相同API。該選項是由兩個支持javacjava命令,如在以下實施例:

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在Java平台,標准版工具參考。

請參閱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語言環境數據通過默認啟用的Java平台,標准版國際指南和JEP 252:使用CLDR語言環境數據的默認

部署

Java部署技術在JDK 9中已棄用,在JDK 11中已刪除。

使用jlinkJDK 9引入的工具打包和部署專用運行時,而不是依賴於預安裝的系統JRE。

刪除了啟動時JRE版本選擇

從JDK 9開始,刪除了請求從發布時啟動的JRE版本的JRE版本的能力。

現代應用程序通常使用Java Web Start(JNLP),本機OS打包系統或活動安裝程序進行部署。這些技術有自己的方法來管理所需的JRE,根據需要查找或下載並更新所需的JRE。這使得啟動程序的啟動時JRE版本選擇已過時。

在以前的版本中,您可以指定啟動應用程序時要使用的JRE版本(或版本范圍)。通過命令行選項和應用程序的JAR文件中的清單條目,可以選擇版本。

從JDK 9開始,java啟動器修改如下:

  • 如果-version:在命令行上給出了該選項,則發出錯誤消息並退出。
  • 如果JRE-Version在JAR文件中找到清單條目,則發出警告消息並繼續。

請參閱JEP 231:刪除啟動時JRE版本選擇。

刪除了對序列化小程序的支持

從JDK 9開始,不支持將applet部署為序列化對象的能力。借助現代壓縮和JVM性能,以這種方式部署applet沒有任何好處。

object該屬性applet標簽和objectjava objectapplet的參數標簽啟動小程序時被忽略。

而不是序列化applet,使用標准部署策略。

JNLP規范更新

JNLP(Java網絡啟動協議)已更新,以消除不一致性,使代碼維護更容易,並增強安全性。

JNLP已更新如下:

  1. &amp;而不是&在JNLP文件中。

    JNLP文件語法符合XML規范,所有JNLP文件都應該能夠由標准XML解析器解析。

    JNLP文件允許您指定復雜的比較。以前,這是通過使用ampersand(&)完成的,但標准XML不支持此功能。如果您正在使用&創建復雜的比較,請&amp;在JNLP文件中替換它。&amp;與所有版本的JNLP兼容。

  2. 將數字版本元素類型與非數字版本元素類型進行比較。

    以前,當將int版本元素與另一個無法解析為int的版本元素進行比較時,版本元素按字典順序通過ASCII值進行比較。

    從JDK 9開始,如果可以解析為inta 的元素是比其他元素更短的字符串,則在按字典順序按ASCII值進行比較之前,將使用前導零填充該元素。這確保不存在圓形。

    在使用版本比較和JNLP servlet的情況下,您應該僅使用數值來表示版本。

  3. java(或j2se)元素中具有嵌套資源的組件擴展。

    這在規范中是允許的。它以前得到了支持,但這種支持沒有反映在規范中。

  4. FX XML擴展。

    該JNLP規范已經增強,一個添加type屬性application-desc元素,並添加子元素paramapplication-desc(因為它已經是applet-desc)。

    這不會導致現有應用程序出現問題,因為仍然支持以前指定JavaFX應用程序的方法。

請參閱JSR-056上的JNLP規范更新。

JDK 9中的安全更新

從JDK 9開始,一些與安全相關的默認值已更改。

JCE管轄權政策文件默認為無限制

如果您的應用程序以前需要Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files,那么您不再需要下載或安裝它們。它們包含在JDK中,默認情況下處於激活狀態。

如果您的國家/地區或用途需要更嚴格的策略,則仍然可以使用有限的Java加密策略文件。

如果默認情況下提供的任一策略文件都不滿足要求,則可以自定義這些策略文件以滿足您的需求。

請參閱文件中的crypto.policySecurity屬性<java-home>/conf/security/java.security,或Java Platform,Standard Edition Security Developer's Guide中的Cryptographic Strength Configuration

建議您咨詢您的出口/進口控制律師或律師以確定具體要求。

創建PKCS12密鑰庫

我們建議您為密鑰庫使用PKCS12格式。此格式是默認密鑰庫類型,基於RSA PKCS12個人信息交換語法標准。

請參閱創建密鑰庫與JSSE使用的Java平台,標准版安全開發人員指南和密鑰工具在Java平台,標准版工具參考。

垃圾收集的變化

本節介紹從JDK 9開始的垃圾回收更改。

使G1成為默認垃圾收集器

Garbage-First垃圾收集器(G1 GC)是JDK 9及更高版本中的默認垃圾收集器。

對於大多數用戶而言,低卡頓收集器(如G1 GC)應該提供比面向吞吐量的收集器更好的整體體驗,例如Parallel GC,它是JDK 8的默認值。

為G1 GC人體工學默認值可調默認的Java平台,標准版Java虛擬機指南有關調整G1 GC的更多信息。

刪除了GC選項

以下GC組合將導致您的應用程序無法在JDK 9及更高版本中啟動:

  • DefNew + CMS
  • ParNew + SerialOld
  • Incremental CMS

CMS的前台模式也已刪除。

Mostly-Concurrent收集器,也稱並發標記清除收集器(Concurrent Mark-Sweep GC,CMS收集器),它管理新生代的方式與Parallel收集器和Serial收集器相同,而在老年代則是盡可能得並發執行,每個垃圾收集器周期只有2次短停頓。

 

被刪除的命令行標志-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統一日志框架記錄在Java平台,標准版工具參考和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工具:

  • 診斷命令:。見。 jcmd <pid> GC.heap_dumpjcmd
  • jmap : jmap -dump. 見jmap

對於CPU分析器功能,請使用與JDK捆綁在一起的Java Flight Recorder。

注意:

Java Flight Recorder需要商業許可才能用於生產。要了解有關商業功能以及如何啟用它們的更多信息,請訪問http://www.oracle.com/technetwork/java/javaseproducts/

請參閱JEP 240:刪除JVM TI hprof代理

刪除了jhat工具

jhat工具是JDK 6中添加的實驗性,不受支持的堆可視化工具。高級堆可視化器和分析器已經可用多年。

刪除了java-rmi.exe和java-rmi.cgi啟動器

java-rmi.exe來自Windows以及java-rmi.cgiLinux和Solaris 的啟動程序已被刪除。

java-rmi.cgi$JAVA_HOME/binLinux和Solaris上。

java-rmi.exe$JAVA_HOME/binWindows上。

這些啟動程序被添加到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_Stuborg.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屬性文件中的Java平台,標准版國際指南。

刪除了特定於macOS的功能

本節包括從JDK 9開始已刪除的特定於macOS的功能。

特定於平台的桌面功能

java.awt.Desktop類包含了蘋果專用的API的替代品com.apple.eawtcom.apple.eio套餐。新API取代了macOS API,並且與平台無關。

com.apple.eawtcom.apple.eio包中的API 是封裝的,因此您無法在JDK 9或更高版本中針對它們進行編譯。但是,它們在運行時仍可訪問,因此編譯為舊版本的現有代碼將繼續運行。最終,使用applecom.apple 包及其子包中的內部類的庫或應用程序 將需要遷移到新的API。

com.apple.concurrentapple.applescript包沒有任何替代刪除。

請參閱JEP 272:特定於平台的桌面功能。

刪除了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 )。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM