The following sections are included in these Release Notes:
These notes describe important changes, enhancements, removed APIs and features, deprecated APIs and features, and other information about JDK 14 and Java SE 14. In some cases, the descriptions provide links to additional detailed information about an issue or a change. This page does not duplicate the descriptions provided by the Java SE 14 (JSR 389) Platform Specification, which provides informative background for all specification changes and might also include the identification of removed or deprecated APIs and features not described here. The Java SE 14 (JSR 389) specification provides links to:
Annex 1: The complete Java SE 14 API Specification.
Annex 2: An annotated API specification showing the exact differences relative to Java SE 13. Informative background for these changes may be found in the list of approved Change Specification Requests for this release.
Annex 3: Java SE 14 Editions of The Java Language Specification and The Java Virtual Machine Specification. The Java SE 14 Editions contain all corrections and clarifications made since the Java SE 13 Editions, as well as additions for new features.
You should be aware of the content in that document as well as the items described in this page.
The descriptions on this Release Note page also identify potential compatibility issues that you might encounter when migrating to JDK 14. The Kinds of Compatibility page on the OpenJDK wiki identifies three types of potential compatibility issues for Java programs used in these descriptions:
Source: Source compatibility preserves the ability to compile existing source code without error.
Binary: Binary compatibility is defined in The Java Language Specification as preserving the ability to link existing class files without error.
Behavioral: Behavioral compatibility includes the semantics of the code that is executed at runtime.
JDK 14 contains IANA time zone data version 2019c. For more information, refer to Timezone Data Versions in the JRE Software.
This section describes some of the enhancements in Java SE 14 and JDK 14. In some cases, the descriptions provide links to additional detailed information about an issue or a change. The APIs described here are those that are provided with the Oracle JDK. It includes a complete implementation of the Java SE 14 Platform and additional Java APIs to support developing, debugging, and monitoring Java applications. Another source of information about important enhancements and new features in Java SE 14 and JDK 14 is the Java SE 14 (JSR 389) Platform Specification, which documents the changes to the specification made between Java SE 13 and Java SE 14. This document includes descriptions of those new features and enhancements that are also changes to the specification. The descriptions also identify potential compatibility issues that you might encounter when migrating to JDK 14.
Currency format instances with accounting style, in which the amount is formatted in parentheses in some locales, can be obtained by calling
NumberFormat.getCurrencyInstance(Locale) with the "u-cf-account" Unicode locale extension. For example in
Locale.US, it will format to "
($3.27)" instead of "
-$3.27". Refer to CLDR's accounting currency format style for additional information.
In JDK 14, the Records (JEP 359) preview feature adds a new class
java.lang package is implicitly imported on demand, that is,
import java.lang.*. If code in an existing source file imports some other package on demand, for example,
import com.myapp.*;, and that other package declares a type called
Record, then code in the existing source file which refers to that type will not compile without change. To make the code compile, import the other package's
Record type using a single-type import, for example,
The specifications of the
ScatteringByteChannel.read() methods have been updated in this release to specify that an
IllegalArgumentException is thrown if (any of) the buffer parameter(s) is read-only. This change merely adjusts the specification to match existing long term behavior.
The Z Garbage Collector (ZGC) is now available as an experimental feature on Windows. To enable it, use the JVM flags
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC. See JEP 365: ZGC on Windows for more information.
The Z Garbage Collector (ZGC) is now available as an experimental feature on macOS. To enable it, use the JVM flags
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC. See JEP 364: ZGC on macOS for more information.
Parallel GC has adopted the same task management mechanism for scheduling parallel tasks as other collectors. This might result in significant performance improvements. Because of this change, the following product flags have been obsoleted:
The G1 garbage collector now tries to allocate and keep objects on the same NUMA node in the young generation across garbage collections. This is similar to Parallel GC NUMA awareness.
G1 attempts to evenly distribute Humongous and Old regions across all available NUMA nodes using a strict interleave. Placement of objects copied from young to old generation is random.
These new NUMA-Aware Memory Allocation heuristics are automatically enabled by using the
-XX:+UseNUMA command line option. See JEP 345: NUMA-Aware Memory Allocation for G1 for more information.
Weak named curves are disabled by default by adding them to the following
disabledAlgorithms security properties: 'jdk.tls.disabledAlgorithms', 'jdk.certpath.disabledAlgorithms', and 'jdk.jar.disabledAlgorithms'. The named curves are listed below.
With 47 weak named curves to be disabled, adding individual named curves to each
disabledAlgorithms property would be overwhelming. To relieve this, a new security property, 'jdk.disabled.namedCurves', is implemented that can list the named curves common to all of the
disabledAlgorithms properties. To use the new property in the
disabledAlgorithms properties, precede the full property name with the keyword
include. Users can still add individual named curves to
disabledAlgorithms properties separate from this new property. No other properties can be included in the
To restore the named curves, remove the
include jdk.disabled.namedCurves either from specific or from all
disabledAlgorithms security properties. To restore one or more curves, remove the specific named curve(s) from the
Curves that are disabled through
jdk.disabled.namedCurves include the following: secp112r1, secp112r2, secp128r1, secp128r2, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
Curves that remain enabled are: secp256r1, secp384r1, secp521r1, X25519, X448
The Apache Santuario library has been upgraded to version 2.1.4. As a result, a new system property
com.sun.org.apache.xml.internal.security.parser.pool-size has been introduced.
This new system property sets the pool size of the internal
DocumentBuilder cache used when processing XML Signatures. The function is equivalent to the
org.apache.xml.security.parser.pool-size system property used in Apache Santuario and has the same default value of 20.
javac "plugins" can now opt-in to be started by default if not started explicitly in the options passed to
javac from the command-line or in the
options argument of an API invocation. This behavior is enabled by implementing the method
Plugin.isDefault() to return
A new method
declaration has been added to
SAX ContentHandler to receive notification of the XML declaration. By implementing this method, applications can receive the values of version, encoding, and standalone attributes exactly as declared in the input document.
This section describes the APIs, features, and options that were removed in Java SE 14 and JDK 14. The APIs described here are those that are provided with the Oracle JDK. It includes a complete implementation of the Java SE 14 Platform and additional Java APIs to support developing, debugging, and monitoring Java applications. Another source of information about important enhancements and new features in Java SE 14 and JDK 14 is the Java SE 14 (JSR 389) Platform Specification, which documents changes to the specification made between Java SE 13 and Java SE 14. This document includes the identification of removed APIs and features not described here. The descriptions below might also identify potential compatibility issues that you could encounter when migrating to JDK 14. See CSRs Approved for JDK 14 for the list of CSRs closed in JDK 14.
The system property
sun.nio.cs.map, added in JDK 1.4.1, has been removed. It was provided for applications to help migrate from the old definition of
Shift_JIS, which was equivalent to MS Windows codepage 932, to the one that is defined by IANA. Applications that are using the mapping property will need to designate the correct charset name based on their needs.
The CMS garbage collector has been removed.
-XX:UseConcMarkSweepGC and aliases
-Xnoconcgc are obsoleted as well as all CMS specific options (too many to list). See JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector for more information.
java.security.acl APIs have been removed. This includes the following classes in that package:
The default key algorithm for the
keytool -genkeypair and
keytool -genseckey commands has been removed. You must now specify the key algorithm by including the
-keyalg option when using the
-genseckey commands. If the
-keyalg option is not specified, the
keytool will terminate with the error message: "The -keyalg option must be specified".
unpack200 tools, added in JDK 5.0, have been removed. The class
java.util.jar.Pack200 and the interfaces
java.util.jar.Pack200.Unpacker have also been removed. These tools and API were deprecated for removal in Java SE 11 with the express intent to remove them in a future release. In addition, in the
jar tool, the
n sub-option to
jar c has been removed. See JEP 367: Remove the Pack200 Tools and API for more information.
Additional sources of information about the APIs, features, and options deprecated in Java SE 14 and JDK 14 include:
You should be aware of the contents in those documents as well as the items described in this release notes page.
The descriptions of deprecated APIs might include references to the deprecation warnings of
forRemoval=true text indicates that a deprecated API might be removed from the next major release. The
forRemoval=false text indicates that a deprecated API is not expected to be removed from the next major release but might be removed in some later release.
The descriptions below also identify potential compatibility issues that you might encounter when migrating to JDK 14. See CSRs Approved for JDK 14 for the list of CSRs closed in JDK 14.
The following methods related to thread suspension in
java.lang.ThreadGroup have been terminally deprecated in this release:
These methods will be removed in a future release.
The ParallelScavenge + SerialOld garbage collector combination has been deprecated. Any use of the
UseParallelOldGC command line option, which is used to enable this garbage collection algorithm combination, will cause a deprecation warning.
The drop-in replacement is to use the ParallelScavenge + ParallelOld garbage collector through
-XX:+UseParallelGC on the command line.
See JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination for more information.
The following named elliptic curves supported by the
SunEC provider have been deprecated:
brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1, secp112r1, secp112r2, secp128r1, secp128r2, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3
The implementations of these curves are targeted to be removed in a subsequent JDK release. A small number of them may be replaced with a more modern implementation.
The OracleUcrypto JCE Provider and its containing module
jdk.crypto.ucrypto have been deprecated and are subject to removal in a future version of the JDK. See JEP 362 for more information.
A number of bugs have been reported against Dark Mode on macOS which require a fix in the JavaRuntimeSupport framework (JRS); an issue has been filed with Apple:
FB6798883: The JavaRuntimeSupport.framework does not work properly in Dark Mode
jdk.serialFilter system property can only be set on the command line. If the filter has not been set on the command line, it can be set can be set with
java.io.ObjectInputFilter.Config.setSerialFilter. Setting the jdk.serialFilter with
java.lang.System.setProperty has no effect.
The specification for
java.lang.Thread::interrupt allows for an implementation to only track the interrupt state for live threads, and previously this is what occurred. As of this release, the interrupt state of a
Thread is always available, and if you interrupt a thread
t before it is started, or after it has terminated, the query
t.isInterrupted() will return true.
The terminally deprecated method
Thread.countStackFrames has been changed in this release to unconditionally throw
This method will be removed in a future release.
MethodType::fromMethodDescriptorString has been changed in this release. When a security manager is present and the
loader parameter is null, it performs a RuntimePermission("getClassLoader") security permission check. This check ensures that access to the system class loader is permitted.
Existing code that calls
MethodType.fromMethodDescriptorString(desc, null) might get a
SecurityException if access to the system class loader is denied. The security policy must be configured to grant the permission. Applications running without a security manager or with a non-null loader are not affected by this change.
MethodHandles::privateLookupIn has been changed. In this release, the caller
Lookup must have both
MODULE access because an application intending to share intra-module access using
MODULE alone will inadvertently also share deep reflection to its own module. In addition, if a
Lookup object is created by
MethodHandles::privateLookupIn teleporting from one module to another module, the
MODULE mode is dropped. In other words,
MethodHandles::privateLookupIn requires that the caller lookup object must be created by a member from the caller's module and not be produced by cross-module teleporting.
For example, a lookup object
L created by calling
MethodHandles.privateLookupIn(C.class, caller) (where C is a class in module M1, and the caller's lookup class is in module M0) can access public members of public class D in module M2 if:
If D in M2 is accessible to M0 but not to M1, lookup object
L will fail to lookup members in D in this release, but would have succeeded in previous releases.
java.lang.invoke.MethodHandles.Lookup::in method throws
IllegalArgumentException if the given
requestedLookupClass is a primitive type, void, or an array class. A
Lookup object never intends to allow a lookup class of primitive type, void, or array class. Consequently, the specification of
Lookup::in has been fixed in Java SE 14.
Lookup object produced by
MethodHandles::privateLookupIn in this release might not have full privilege access. A
Lookup that possesses both PRIVATE and MODULE access modes is said to possess full privilege access that can be tested with the
Lookup::hasFullPrivilegeAccess method. In previous releases, a
Lookup returned from
MethodHandles::privateLookupIn could be used to look up caller-sensitive methods. In Java SE 14, if a
Lookup does not have full privilege access (even though it has private access mode), it might fail to look up caller-sensitive methods.
send methods defined by
MulticastSocket have been changed to throw an
IllegalArgumentException if the socket is not connected and the
DatagramPacket doesn't have a socket address. Prior to this change, these methods threw a
getOption has been changed to conform to the behavior described in
MulticastSocket.getOption(StandardSocketOptions.IP_MULTICAST_IF) now returns
null if no interface has been set.
setOption have been changed to conform to the behavior described in the
MulticastSocket.getOption(StandardSocketOptions.IP_MULTICAST_LOOP) now returns true if loopback mode is enabled. Setting
MulticastSocket.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true) enables loopback mode.
InetSocketAddress::toString has been improved regarding the handling of IPv6 addresses. The implementation now encloses the IPv6 literal in brackets, which adheres to the specification outlined in RFC2732.
Additionally, the string format for unresolved addresses has been changed. The method now represents the literal IP address with the token
<unresolved>. For example:
foo/<unresolved>:80 instead of
foo:80. This is based on
InetAddress::toString, which returns a string of the form "hostname / literal IP address". To retrieve a string representation of the hostname, or the string form of the address if it doesn't have a hostname, use
InetSocketAddress::getHostString, rather than parsing the string representation.
DatagramChannel implementation has been updated in this release so that the
disconnect method attempts to workaround Linux kernel behavior that reverts the local port to 0 after dissolving the association. The issue arises when a
DatagramChannel is initially bound to an ephemeral port, connected (by calling its
connect method), and then disconnected (by calling its
disconnect method). The workaround in the
DatagramChannel::disconnect is to attempt to re-bind the channel's socket to its original port. This usually succeeds, but if it fails, an
IOException is thrown. This workaround has been used in the
DatagramSocket implementation for several releases.
As part of this change, the
DatagramChannel::disconnect has been updated with an API note to make it clear that an
IOException might leave the channel's socket in an unspecified state. The API note also strongly recommends that the channel be closed when the
java.rmi.Remote marker interface identifies interfaces containing methods that can be invoked remotely by using the following specification:
java.rmi.Remotecan be invoked remotely
Remotedirectly or indirectly cannot be invoked remotely
This affects remote objects in the
java.rmi.registry.Registry and any other remote object.
java.text.CompactNumberFormat is now capable of dealing with plural forms. For example, the number
2,000,000 is formatted to
"2 Millionen" in
LONG style, whereas
"1 Million" in the German language.
Locale data based on Unicode Consortium's CLDR has been upgraded to their version 36. For the detailed locale data changes, please refer to the Unicode Consortium's CLDR release notes:
The specification for
ExecutableElement.getReceiverType requires it to return
NOTYPE when a receiver type is not defined. The implementation has been changed to return
NOTYPE in this case rather than null.
The semantics of the
com.sun.jndi.dns.timeout.initial property of the JNDI DNS provider implementation have been amended. The value of this timeout now uniformly applies to both UDP and TCP queries. Previously it applied only to UDP queries.
The default value of
UseAOT has been changed from
disabled, and the following AOT support related flags have been changed to experimental:
glibc library allocates some thread-local storage (TLS) in the stack of a newly created thread, leaving less stack than requested for the thread to do its work. This is particularly a problem for threads with small stack sizes. It is an inherited issue from a well-known
glibc problem, 'Program with large TLS segments fail'  and has been observed in Java applications. In one of the reported JVM failure instances, the issue manifests as a
StackOverflowError on the process reaper thread, which has a small stack size. The
java.lang.Thread constructor enables users to specify the stack size for a new thread. The created thread may encounter the TLS problem when the specified size is too small to accommodate the on-stack TLS blocks.
In JDK 8, a system property,
jdk.lang.processReaperUseDefaultStackSize, was introduced to address the TLS issue only for reaper threads. Setting the property gives a bigger stack size to the reaper threads.
To address the issue for all threads, a general purpose workaround was implemented in Java which adjusts thread stack size for TLS. It can be enabled by using the
AdjustStackSizeForTLS command-line option:
When creating a new thread, if
AdjustStackSizeForTLS is true, the static TLS area size is added to the user requested stack size.
AdjustStackSizeForTLS is disabled by default.
Reference:  Bug 11787 - Program with large TLS segments fail
A new option is available to provide more helpful
If the option is set, on encountering a null pointer, the JVM analyzes the program to determine which reference was
null and then provides the details as part of
NullPointerException.getMessage(). In addition to the exception message, the method, filename, and line number are also returned.
By default, this option is disabled.
In JDK 14, CDS runtime classpath validation is now more forgiving when dealing with files in the classpath that do not exist.
At CDS archive dump time, all non-existent elements in the classpath are automatically stripped. For example, if the command is:
java -cp nosuchfile.jar:hello.jar -Xshare:dump \
after removing the non-existing elements, the classpath recorded in
Also, at run time, when the CDS archive is loaded, all non-existent elements in the classpath are ignored. With the previous example, all of the following commands will successfully load the archive:
java -cp nosuchfile.jar:hello.jar -Xshare:on \
java -cp hello.jar -Xshare:on \
java -cp alsonosuchfile.jar:hello.jar -Xshare:on \
In JDK 13 and earlier, only (1) is allowed while (2) and (3) would trigger an error.
A TLS server certificate must be an exact match of a trusted certificate on the client in order for it to be trusted when establishing a TLS connection.
New checks have been added to ensure that trust anchors are CA certificates and contain proper extensions. Trust anchors are used to validate certificate chains used in TLS and signed code. Trust anchor certificates must include a Basic Constraints extension with the cA field set to true. Also, if they include a Key Usage extension, the keyCertSign bit must be set.
A new system property named
jdk.security.allowNonCaAnchor has been introduced to restore the previous behavior, if necessary. If the property is set to the empty String or "true" (case-insensitive), trust anchor certificates can be used if they do not have proper CA extensions.
The default value of this property, if not set, is "false".
Note that the property does not apply to X.509 v1 certificates (since they don't support extensions).
This property is currently used by the JDK implementation. It is not guaranteed to be supported by other Java SE implementations.
The following root certificate has been added to the cacerts truststore:
DN: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
The following root certificates have been added to the cacerts truststore:
DN: CN=Amazon Root CA 1, O=Amazon, C=US
DN: CN=Amazon Root CA 2, O=Amazon, C=US
DN: CN=Amazon Root CA 3, O=Amazon, C=US
DN: CN=Amazon Root CA 4, O=Amazon, C=US
The protected constructor of
javax.crypto.Cipher has been changed to throw
IllegalArgumentException instead of
NullPointerException if the supplied arguments are deemed invalid for constructing the
Cipher object. If the provider argument is null, the constructor will throw
NullPointerException as before. Both exceptions are now documented in the javadoc specification of the protected constructor.
Prior to this release, the SunJCE provider incorrectly returned a
Cipher instance for the "AES/GCM/NoPadding" transformation when a caller requested "AES/GCM/PKCS5Padding". The SunJCE provider now throws
NoSuchAlgorithmException when "AES/GCM/PKCS5Padding" is requested. If you are impacted by this issue, the workaround is to use "AES/GCM/NoPadding" instead.
SSLv2Hello and SSLv3 have been removed from the default enabled TLS protocols.
After this update, if SSLv3 is removed from the
jdk.tls.disabledAlgorithms security property, the
SSLParameters.getProtocols() APIs will return "TLSv1.3, TLSv1.2, TLSv1.1, TLSv1". "SSLv3" will not be returned in this list.
If a client or server still needs to use the SSLv3 protocol they can do so by enabling it through the
jdk.tls.server.protocols system properties or with the
DelegationPermission object is created and the
principals argument does not contain a pair of principals, an
IllegalArgumentException is now thrown.
Both core reflection and
javac, through annotation processing, have objects representing annotations. The
toString output for the two kinds of annotation objects now follow the same conventions. These conventions allow the output to be used in source code.
Prior to this release, the
javax.xml.transform.ErrorListener specification defined that the default
ErrorListener implementation reported warnings and errors to
System.out in some cases. This requirement has been removed as of this release and the default
ErrorListener now takes no action for warnings and recoverable errors; and in the case of a severe error, throws a
It is recommended that applications always register their own
ErrorListener to ensure proper handling of warnings and errors.
Although we have stated the goal to have OpenJDK and Oracle JDK binaries be as close to each other as possible there remains, at least for JDK 13, several differences between the two options.
The current differences are: