Oracle JDK迁移指南,JDK11变化详解,JDK8升级JDK11详细指南
本文于2043天之前发表,文中内容可能已经过时。
Oracle JDK迁移指南
第11版
E94894-03
2019年7月
入门
本指南的目的是帮助您识别潜在问题,并在将现有Java应用程序迁移到最新JDK版本时为您提供有关如何继续的建议。该指南还强调了对最新版本所做的重大更改和增强。
本指南包含以下部分:
JDK 11发布的重大变化
在将应用程序迁移到JDK 11之前,您应该了解它与JDK 10版本之间的更新和更改。如果要从JDK 8迁移,则还应熟悉从JDK 8迁移到以后的JDK版本中描述的JDK 8和更高版本之间的差异。
以下是JDK 11中的一些重要更改:
- Oracle不再提供JRE和Server JRE下载; 因此,自动更新不再可用。
- Oracle不再提供32位Windows下载。
- Java Web Start,Java插件和Java控制面板在JDK中不可用。请参阅删除部署堆栈。
- 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发行版中的安全更新
JDK 11版本包括传输层安全性(TLS)1.3规范(RFC 8446)的实现。
TLS 1.3是传输层安全性(TLS)协议的最新版本(2018年8月),默认情况下在JDK 11中启用。该版本不仅关注速度改进,还通过强调现代加密技术来更新协议的整体安全性。实践,并禁止过时或弱的加密算法。(例如,不再允许RSA密钥交换和普通DSA签名。)
TLS 1.3协议中添加了一些功能以提高向后兼容性,但有几个问题需要注意。有关详细信息,请参阅JEP 332。
删除安全证书
已从JDK 11中的密钥库中删除以下根证书:
已从JDK 11中的信任库中删除以下根证书:
使用已删除的证书的产品可能不再有效。如果需要这些证书,则必须使用缺少的证书配置和填充cacerts。为了证书添加到信任,看到密钥工具在Java平台,标准版工具参考指南。
删除了API,工具和组件
本节提供有关在JDK 11中删除的API,工具和组件的详细信息。
在JDK 11中删除了API
JDK 11中删除了以下API。许多这些API在以前的版本中已弃用,并且已被更新的API替换。有关可能的替代方案的信息,请参阅JDK 11 API规范。
1 | javax.security.auth.Policy |
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开始生成错误。
举个例子:
1
static Object _ = new Object();
此代码从编译器生成以下错误消息:
1
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及更高版本中,这些值会导致错误。1
2
3
4>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类文件。在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
,您将看到:
1 | >jdeps -jdkinternals Sample.class |
如果您使用Maven,则可以使用jdeps
插件。
有关jdeps
语法,请参阅Java平台标准版工具参考中的jdeps。
请记住,这jdeps
是一个静态分析工具,代码的静态分析可能无法提供完整的依赖项列表。如果代码使用反射来调用内部API,则jdeps
不会发出警告。
从JDK 8迁移到以后的JDK版本
JDK 8和后来的JDK版本之间发生了重大变化。
Every new Java SE release introduces some binary, source, and behavioral incompatibilities with previous releases. The modularization of the Java SE Platform that happened in JDK 9 brought many benefits, but also many changes. Code that uses only official Java SE Platform APIs and supported JDK-specific APIs should continue to work without change. Code that uses JDK-internal APIs should continue to run but should be migrated to use the supported APIs.
The following sections describe the changes in the JDK package and APIs that you should be aware of when migrating your JDK 8 applications to later JDK releases.
Look at the list of changes that you may encounter as you run your application.
- New Version-String Scheme
- Understanding Runtime Access Warnings
- Changes to the Installed JDK/JRE Image
- Removed or Changed APIs
- Deployment
- Security Updates in JDK 9
- Changes to Garbage Collection
- Removed Tools and Components
- Removed macOS-Specific Features
When your application is running successfully on the latest version of JDK, review Next Steps, which will help you avoid problems with future releases.
Understanding Runtime Access Warnings
Some tools and libraries use reflection to access parts of the JDK that are meant for internal use only. This illegal reflective access will be disabled in a future release of the JDK. Currently, it is permitted by default and a warning is issued.
For example, here is the warning issued when starting Jython:
1 | >java -jar jython-standalone-2.7.0.jar |
如果您看到这样的警告,请联系工具或库的维护人员。警告的第二行命名精确的JAR文件,其代码使用反射来访问JDK的内部部分。
默认情况下,在java
启动程序启动的进程的生命周期中,最多会发出一条有关反射访问的警告。警告的确切时间取决于执行反射访问操作的工具和库的行为。警告可能会在过程的生命周期的早期出现,也可能在启动后很长时间出现。
您可以使用--add-opens
命令行标志在逐个库的基础上禁用警告消息。例如,您可以通过以下方式启动Jython:
1 | >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 |
这次,不发出警告,因为java
调用明确地确认了反射访问。如您所见,您可能需要指定多个--add-opens
标志来涵盖类路径上的库尝试的所有反射访问操作。
为了更好地理解工具和库的行为,可以使用命令行标志。该标志导致为每个非法反射访问操作发出警告消息。此外,您还可以通过设置获取有关非法反射访问操作(包括堆栈跟踪)的详细信息。 --illegal-access=warn``--illegal-access=debug
如果您更新了库,或者获得了库,那么您可以尝试使用命令行标志。除了由其他命令行选项启用的操作外,它禁用所有反射访问操作,例如。这将是未来版本中的默认模式。 --illegal-access=deny``--add-opens
有两个选项可以让您以特定方式打破封装。您可以结合使用它们,或者如前所述,来抑制警告。 --illegal-access=deny
- 如果需要使用已无法访问的内部API,请使用
--add-exports
运行时选项。您还可以--add-exports
在编译时使用来访问内部API。 - 如果必须允许类路径上的代码进行深入反射以访问非公共成员,请使用该
--add-opens
选项。
如果要禁止所有反射访问警告,请在需要时使用--add-exports
和--add-opens
选项。
–add-exports
如果必须使用默认情况下无法访问的内部API,则可以使用--add-exports
命令行选项中断封装。
该--add-exports
1 | --add-exports <source-module>/<package>=<target-module>(,<target-module>)* |
其中<source-module>``<target-module>``<package>
The --add-exports
option allows code in the target module to access types in the named package of the source module if the target module reads the source module.
As a special case, if the , then the source package is exported to all unnamed modules, whether they exist initially or are created later on. For example:This example allows code in all unnamed modules (code on the class path) to access the public members of public types injava.management/sun.management
If an application package of thejava.management
module, then the access that it requires can be granted in this way:
You can also break encapsulation with the JAR file manifest:
1 | Add-Exports:java.management/sun.management |
Use the --add-exports
option carefully. You can use it to gain access to an internal API of a library module, or even of the JDK itself, but you do so at your own risk. If that internal API changes or is removed, then your library or application fails.
See also JEP 261.
–add-opens
If you have to allow code on the class path to do deep reflection to access nonpublic members, then use the --add-opens
runtime option.
Some libraries do deep reflection, meaning setAccessible(true)
, so they can access all members, including private ones. You can grant this access using the --add-opens
option on the java
command line. No warning messages are generated as a result of using this option.
If --illegal-access=deny
, and you see IllegalAccessException
or InaccessibleObjectException
messages at runtime, you could use the --add-opens
runtime option, basing the arguments upon the information shown in the exception message.
The syntax for
1 | --add-opens module/package=target-module(,target-module)* |
This option allows , regardless of the module declaration.
As a special case, if the , then the source package is exported to all unnamed modules, whether they exist initially or are created later on. For example:This example allows all of the code on the class path to access nonpublic members of public types in thejava.management/sun.management
package.
Note:
If you are using the JNI Invocation API, including, for example, a Java Web Start JNLP file, you must include an equals sign between
1 | <j2se version="10" java-vm-args="--add-opens=module/package=ALL-UNNAMED" /> |
The equals sign between --add-opens
and its value is optional on the command line.
New Version-String Scheme
JDK 10 introduced some minor changes, to better accommodate the time-based release model, to the version-string scheme introduced in JDK 9. JDK 11 retains the version string format that was introduced in JDK 10.
If your code relies on the version-string format to distinguish major, minor, security, and patch update releases, then you may need to update it.
The format of the new version-string is:
1 | $FEATURE.$INTERIM.$UPDATE.$PATCH |
A simple Java API to parse, validate, and compare version strings has been added. See java.lang.Runtime.Version.
See Version String Format in Java Platform, Standard Edition Installation Guide .
For the changes to the version string introduced in JDK 9, see JEP 223: New Version-String Scheme .
For the version string changes introduced in JDK 10, see JEP 322: Time-Based Release Versioning.
Changes to the Installed JDK/JRE Image
Significant changes have been made to the JDK and JRE.
Changed JDK and JRE Layout
After you install the JDK, if you look at the file system, you’ll notice that the directory layout is different from that of releases before JDK 9.
JDK 11
JDK 11 does not have the JRE image. See Installed Directory Structure of JDK in Java Platform, Standard Edition Installation Guide.
JDK 9 and JDK 10
Prior releases produced two types of runtime images: the JRE, which was a complete implementation of the Java SE Platform, and the JDK, which included the entire JRE in a jre/
directory, plus development tools and libraries.
In JDK 9 and and JDK 10, the JDK and JRE are two types of modular runtime images, where each contains the following directories:
bin
: contains binary executables.conf
: contains.properties
,.policy
, and other kinds of files intended to be edited by developers, deployers, and end users. These files were formerly found in thelib
directory or its subdirectories.lib
: contains dynamically linked libraries and the complete internal implementation of the JDK.
在JDK 9和JDK 10中,仍然有单独的JDK和JRE下载,但每个都具有相同的目录结构。JDK映像包含历史上在JDK中找到的额外工具和库。没有jdk/
与jre/
包装目录相对应,并且二进制文件(例如java
命令)不会重复。
请参阅JEP 220:模块化运行时映像。
新的类加载器实现
JDK 9及更高版本维护自1.2版本以来存在的类加载器的层次结构。但是,已经进行了以下更改以实现模块系统:
应用程序类加载器不再是URLClassLoader的实例,而是内部类的实例。它是模块中类的默认加载器,既不是Java SE也不是JDK模块。
扩展类加载器已重命名; 它现在是平台类加载器。通过平台类加载器可以保证Java SE平台中的所有类都可见。
仅仅因为通过平台类加载器可见类并不意味着该类实际上是由平台类加载器定义的。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命名存储在运行时映像中的模块,类和资源,而不会泄露图像的内部结构或格式。例如:
1
ClassLoader.getSystemResource("java/lang/Class.class");
在JDK 8上运行时,此方法返回以下形式的JAR URL:
1
jar:file:/usr/local/jdk8/jre/lib/rt.jar!/java/lang/Class.class
它嵌入一个文件URL来命名运行时映像中的实际JAR文件。
模块化图像不包含任何JAR文件,因此这种形式的URL毫无意义。在JDK 9及更高版本中,此方法返回:
1
jrt:/java.base/java/lang/Class.class
The java.security.CodeSource API and security policy files use URLs to name the locations of code bases that are to be granted specific permissions. See Policy File Syntax in Java Platform, Standard Edition Security Developer’s Guide. Components of the runtime system that require specific permissions are currently identified in the
conf/security/java.policy
file by using file URLs.Older versions of IDEs and other development tools require the ability to enumerate the class and resource files stored in a runtime image, and to read their contents directly by opening and reading
rt.jar
and similar files. This isn’t possible with a modular image.
Removed Extension Mechanism in JDK 9
In JDK 8 and earlier, the extension mechanism made it possible for the runtime environment to find and load extension classes without specifically naming them on the class path. Starting from JDK 9, if you need to use the extension classes, ensure that the JAR files are on the class path.
In JDK 9 and JDK 10, the javac
compiler and java
launcher will exit if the java.ext.dirs
system property is set, or if the lib/ext
directory exists. To additionally check the platform-specific systemwide directory, specify the -XX:+CheckEndorsedAndExtDirs
command-line option. This causes the same exit behavior to occur if the directory exists and isn’t empty. The extension class loader is retained in JDK 9 (and later releases) and is specified as the platform class loader (see getPlatformClassLoader.) However, in JDK 11, this option is obsolete and a warning is issued when it is used.
The following error means that your system is configured to use the extension mechanism:
1 | <JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead. |
You’ll see a similar error if the java.ext.dirs
system property is set.
To fix this error, remove the ext/
directory or the java.ext.dirs
system property.
See JEP 220: Modular Run-Time Images.
Removed Endorsed Standards Override Mechanism
The java.endorsed.dirs
system property and the lib/endorsed
directory are no longer present. The javac
compiler and java
launcher will exit if either one is detected.
Starting from JDK 9, you can use upgradeable modules or put the JAR files on the class path.
This mechanism was intended for application servers to override components used in the JDK. Packages to be updated would be placed into JAR files, and the system property java.endorsed.dirs
would tell the Java runtime environment where to find them. If a value for this property wasn’t specified, then the default of $JAVA_HOME/lib/endorsed
was used.
In JDK 8, you can use the -XX:+CheckEndorsedAndExtDirs
command-line argument to check for such directories anywhere on the system.
In JDK 9 and later releases, the javac
compiler and java
launcher will exit if the java.endorsed.dirs
system property is set, or if the lib/endorsed
directory exists.
The following error means that your system is configured to use the endorsed standards override mechanism:
1 | <JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs |
如果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。
可以从JDK中删除支持的API,但只能通知。通过运行静态分析工具jdeprscan,了解您的代码是否使用了弃用的API 。
java。*在JDK 9中删除的API包括java.util.logging.LogManager和java.util.jar.Pack200包中以前弃用的方法:
1 | java.util.logging.LogManager.addPropertyChangeListener |
删除和将来删除sun.misc和sun.reflect API
与java。* API不同,几乎所有sun。* API都不受支持,JDK内部API,并且可能随时消失。
在JDK 9中删除了一些sun。* API。值得注意的是,sun.misc.BASE64Encoder和sun.misc.BASE64Decoder被删除了。而是使用受支持的java.util.Base64类,该类在JDK 8中添加。
如果您使用这些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
要查看是否已设置对等方:
1
if (component.getPeer() != null) { .. }
将其替换为JDK 1.1 API中的
Component.isDisplayable()
:
1
2public boolean isDisplayable() {
return getPeer() != null;要测试组件是否轻量级:
1
if (component.getPeer() instanceof LightweightPeer) ..
将其替换为JDK 1.2 API中的
Component.isLightweight()
:
1
2public 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
命令,如在以下实施例:
1 | javac --limit-modules java.base,java.logging MyApp.java |
为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中已删除。
使用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的参数标签启动小程序时被忽略。
而不是序列化小程序,使用标准部署策略。
JNLP规范更新
JNLP(Java网络启动协议)已更新,以消除不一致性,使代码维护更容易,并增强安全性。
JNLP已更新如下:
&
&1
2
3
而不是java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在JNLP文件中。
JNLP文件语法符合XML规范,所有JNLP文件都应该能够由标准XML解析器解析。
JNLP文件允许您指定复杂的比较。以前,这是通过使用ampersand(`&`)完成的,但标准XML不支持此功能。如果您正在使用`&`创建复杂的比较,请`&`在JNLP文件中替换它。`&`与所有版本的JNLP兼容。
2. 将数字版本元素类型与非数字版本元素类型进行比较。
以前,当将`int`版本元素与另一个无法解析为`int`的版本元素进行比较时,版本元素按字典顺序通过ASCII值进行比较。
从JDK 9开始,如果可以解析为`int`a 的元素是一个比另一个元素更短的字符串,则在按字典顺序按ASCII值进行比较之前,它将用前导零填充。这确保不存在圆形。
在使用版本比较和JNLP servlet的情况下,您应该仅使用数值来表示版本。
3. 具有j2se1
2
3
(或Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.01
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
)元素中嵌套资源的组件扩展。
这在规范中是允许的。它以前得到了支持,但这种支持没有反映在规范中。
4. FX XML扩展。
该JNLP规范已经增强,一个添加`type`属性`application-desc`元素,并添加子元素`param`中`application-desc`(因为它已经是`applet-desc`)。
这不会导致现有应用程序出现问题,因为仍然支持以前指定JavaFX应用程序的方法。
请参阅[JSR-056上](https://jcp.org/aboutJava/communityprocess/maintenance/jsr056/9.html)的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`,或Java平台标准版安全开发人员指南中的[加密强度配置](https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/11/migrate&id=JSSEC-GUID-EFA5AC2D-644E-4CD9-8523-C6D3936D5FB1)。
建议您咨询您的出口/进口控制律师或律师,以确定具体要求。
### 创建PKCS12密钥库
我们建议您为密钥库使用PKCS12格式。此格式是默认密钥库类型,基于RSA PKCS12个人信息交换语法标准。
请参阅[创建密钥库与JSSE使用](https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/11/migrate&id=JSSEC-GUID-3D26386B-BC7A-41BB-AC70-80E6CD147D6F)的Java平台,标准版安全开发人员指南和[密钥工具](http://www.oracle.com/pls/topic/lookup?ctx=javase12&id=keytool_tool_reference)在Java平台,标准版工具参考。
### 垃圾收集的变化
本节介绍从JDK 9开始的垃圾回收更改。
### 使G1成为默认垃圾收集器
Garbage-First垃圾收集器(G1 GC)是JDK 9及更高版本中的默认垃圾收集器。
对于大多数用户而言,低暂停收集器(例如G1 GC)应该提供比面向吞吐量的收集器更好的整体体验,例如Parallel GC,它是JDK 8的默认值。
见[为G1 GC人体工学默认值](https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/11/migrate&id=JSGCT-GUID-082C967F-2DAC-4B59-8A81-0CEC6EEB9016)和[可调默认](https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/11/migrate&id=JSGCT-GUID-379B3888-FE24-4C3F-9E38-26434EB04F89)的Java平台,标准版Java虚拟机指南有关调整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组合](http://openjdk.java.net/jeps/214)。
删除了永久世代
在JDK 8中删除了永久代,并且相关的VM选项会导致打印警告。您应该从脚本中删除这些选项:
- `-XX:MaxPermSize=size`
- `-XX:PermSize=size`
在JDK 9及更高版本中,JVM会显示如下警告:
1 |
|
javac -h
### 删除了JavaDB
JavaDB是Apache Derby的品牌重塑,不再包含在JDK中。
JavaDB与JDK 7和JDK 8捆绑在一起。它`db`位于JDK安装目录的目录中。
您可以从[Apache Derby Downloads](https://db.apache.org/derby/derby_downloads.html)下载并安装Apache Derby 。
### 删除了JVM TI hprof代理
该`hprof`代理程序库已被删除。
该`hprof`剂被写为演示代码[JVM工具界面](https://docs.oracle.com/javase/8/docs/technotes/guides/jvmti/index.html),并没有打算成为一个生产工具。`hprof`代理的有用功能已被更好的替代方案所取代,包括JDK中包含的一些替代方案。
要以`hprof`格式创建堆转储,请使用诊断命令(`jcmd`)或`jmap`工具:
- 诊断命令:。见。 `jcmd <pid> GC.heap_dump``jcmd`
- jmap : `jmap -dump`. 见`jmap`。
对于CPU Profiler功能,请使用与JDK捆绑在一起的Java Flight Recorder。
注意:
Java Flight Recorder需要商业许可才能用于生产。要了解有关商业功能以及如何启用它们的更多信息,请访问http://www.oracle.com/technetwork/java/javaseproducts/
请参阅[JEP 240:删除JVM TI hprof代理](http://openjdk.java.net/jeps/240)。
### 删除了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和对象序列化。](https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/faq.html#servlet)
### 从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开源项目站点](https://visualvm.github.io/)获取它。
### 删除了native2ascii工具
该`native2ascii`工具已从JDK中删除。由于JDK 9及更高版本支持基于UTF-8的属性资源包,因此不再需要基于UTF-8的属性资源包到ISO-8859-1的转换工具。
见[UTF-8属性文件](https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/11/migrate&id=JSINT-GUID-974CF488-23E8-4963-A322-82006A7A14C7)中的Java平台,标准版国际指南。
### 删除了特定于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`包没有任何替代删除。
请参阅[JEP 272:特定于平台的桌面功能。](http://openjdk.java.net/jeps/272)
### 删除了AppleScript引擎
AppleScript引擎是一个特定于平台的javax.script实现,在JDK中没有任何替换,已被删除。
AppleScript引擎在最近的版本中几乎无法使用。该功能仅适用于已在系统上具有Apple版本`AppleScriptEngine.jar`文件的系统上的JDK 7或JDK 8 。
### 下一步
在JDK 11上运行应用程序之后,这里有一些建议可以帮助您从Java SE平台中获得最大收益:
- 如果需要,使用[javac](http://www.oracle.com/pls/topic/lookup?ctx=javase12&id=javac_tool_reference)工具中的新`-–release`标志交叉编译到平台的旧版本 。
- 利用IDE的建议,使用最新功能更新代码。
- 通过运行静态分析工具[jdeprscan,](http://www.oracle.com/pls/topic/lookup?ctx=javase11&id=jdeprscan_tool_reference)了解您的代码是否使用了弃用的API 。正如本指南中已经提到的,API可以从JDK中删除,但只能提前通知。
- 熟悉多版本JAR文件等新功能(参见[jar](http://www.oracle.com/pls/topic/lookup?ctx=javase11&id=jar_tool_reference))。
### 文档可访问性
有关Oracle对辅助功能的承诺的信息,请访问Oracle辅助功能计划网站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-03
版权所有©2017,2019,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之间的适用协议中规定的除外。