JDK 20 Release Notes

New Features

DTLS Resumption Uses HelloVerifyRequest Messages (JDK-8287411)

security-libs/javax.net.ssl

With this fix, the SunJSSE DTLS implementation will exchange cookies for all handshakes, both new and resumed, by default unless the System property jdk.tls.enableDtlsResumeCookie is false. The property only affects the cookie exchange for resumption.

(D)TLS Key Exchange Named Groups (JDK-8281236)

security-libs/javax.net.ssl

New Java SE APIs, javax.net.ssl.SSLParameters.getNamedGroups() and javax.net.ssl.SSLParameters.setNamedGroups(), have been added to allow applications to customize the named groups of key exchange algorithms used in individual TLS or DTLS connections.

Note that the underlying provider may define the default named groups for each TLS or DTLS connection. Applications may also use the existing jdk.tls.namedGroups system property to customize the provider-specific default named groups. If not null, the named groups passed to the setNamedGroups() method will override the default named groups for the specified TLS or DTLS connections.

Note that a provider may not have been updated to support the new APIs and in that case may ignore the named groups that are set. The JDK SunJSSE provider supports this method. It is recommended that third party providers add support for these methods when they add support for JDK 19 or later releases.

Print warning to standard error if bad java.io.tmpdir setting is detected (JDK-8290313)

core-libs/java.lang

A new warning is now printed to the standard error stream at startup if a custom java.io.tmpdir system property is defined but the directory doesn't exist. The warning printed is:

"WARNING: java.io.tmpdir directory does not exist"

Support Unicode 15.0 (JDK-8284842)

core-libs/java.lang

This release upgrades the Unicode version to 15.0, which includes updated versions of the Unicode Character Database, Unicode Standard Annexes #9, #15, and #29: The java.lang.Character class supports Unicode Character Database, which adds 4,489 characters, for a total of 149,186 characters. These additions include 2 new scripts, for a total of 161 scripts, as well as 20 new emoji characters, and 4,193 CJK (Chinese, Japanese, and Korean) ideographs. The java.text.Bidi and java.text.Normalizer classes support Unicode Standard Annexes, #9 and #15, respectively. The java.util.regex package supports Extended Grapheme Clusters based on the Unicode Standard Annex #29. For more detail about Unicode 15.0, refer to the Unicode Consortium’s release note.

Add GarbageCollectorMXBean for Remark and Cleanup Pause Time in G1 (JDK-8297247)

hotspot/gc

A new GarbageCollectorMXBean named "G1 Concurrent GC" has been added to the G1 garbage collector.

This GarbageCollectorMXBean reports the occurrence and durations of the Remark and Cleanup garbage collection pauses.

Similar to the "CGC" field from jstat -gcutil, a complete concurrent mark cycle will increase the bean's collection counter by 2, one for the Remark and one for the Cleanup pauses. These pauses now also update the "G1 Old Gen" MemoryManagerMXBean memory pool.

New JFR Event: jdk.InitialSecurityProperty (JDK-8292177)

security-libs/java.security

A new Java Flight Recorder (JFR) event has been added to record details of initial security properties when loaded via the java.security.Security class.

The new event name is jdk.InitialSecurityProperty and contains the following fields:

Field name Field Description
key Security Property Key
value Corresponding Security Property Value

This new JFR event is enabled by default. The java.security.debug=properties system property will also now print initial security properties to the standard error stream. With this new event and the already available jdk.SecurityPropertyModification event (when enabled since it is not enabled by default), a JFR recording can now monitor the initial settings of all security properties and any subsequent changes.

New JFR Event: jdk.SecurityProviderService (JDK-8254711)

security-libs/java.security

A new Java Flight Recorder (JFR) event has been added to record details of java.security.Provider.getService(String type, String algorithm) calls.

The new event name is jdk.SecurityProviderService and contains the following fields:

Field name Field Description
type Type of Service
algorithm Algorithm Name
provider Security Provider

This event is disabled by default and can be enabled via the JFR configuration files or via standard JFR options.

Provide Poly1305 Intrinsic on x86_64 platforms with AVX512 instructions (JDK-8288047)

security-libs/javax.crypto

This feature delivers optimized intrinsics using AVX512 instructions on x86_64 platforms for the Poly1305 Message Authentication Code algorithm of the SunJCE provider. This optimization is enabled by default on supporting x86_64 platforms, but may be disabled by providing the -XX:+UnlockDiagnosticVMOptions -XX:-UsePoly1305Intrinsics command-line options.

Provide ChaCha20 Intrinsics on x86_64 and aarch64 Platforms (JDK-8247645)

security-libs/javax.crypto

This feature delivers optimized intrinsic implementations for the ChaCha20 cipher supplied by the SunJCE provider. These optimized routines are designed for x86_64 chipsets that support the AVX, AVX2 and/or AVX512 instruction sets, and aarch64 chips supporting the Advanced SIMD instruction set. These intrinsics are enabled by default on supporting platforms, but may be disabled by providing the -XX:-UseChaCha20Intrinsics command-line option to Java. Flags that control intrinsics require the option -XX:+UnlockDiagnosticVMOptions.

New 'jmod --compress' Command Line Option (JDK-8293499)

tools

A new --compress command line option has been added to the jmod tool to specify the compression level while creating the JMOD archive. The accepted values are zip-[0-9], where zip-0 provides no compression, and zip-9 provides the best compression. Default is zip-6.

Javac Warns about Type Casts in Compound Assignments with Possible Lossy Conversions (JDK-8244681)

tools/javac

New lint option lossy-conversions has been added to javac to warn about type casts in compound assignments with possible lossy conversions. If the type of the right-hand operand of a compound assignment is not assignment compatible with the type of the variable, a cast is implied and possible lossy conversion may occur.

The new warnings can be suppressed using @SuppressWarnings("lossy-conversions").

Removed Features and Options

Thread.suspend/resume Changed to Throw UnsupportedOperationException (JDK-8249627)

core-libs/java.lang

The ability to suspend or resume a thread with the Thread.suspend() and Thread.resume() methods has been removed in this release. The methods have been changed to throw UnsupportedOperationException. These methods were inherently deadlock prone and have been deprecated since JDK 1.2 (1998). The corresponding methods in ThreadGroup, to suspend or resume a group of threads, were changed to throw UnsupportedOperationException in Java 19.

Thread.Stop Changed to Throw UnsupportedOperationException (JDK-8289610)

core-libs/java.lang

The ability to "stop" a thread with the Thread.stop() method has been removed in this release. The method has been changed to throw UnsupportedOperationException. Stopping a thread by causing it to throw java.lang.ThreadDeath was inherently unsafe. The stop method has been deprecated since JDK 1.2 (1998). The corresponding method in ThreadGroup, to "stop" a group of threads, was changed to throw UnsupportedOperationException in Java 19.

As part of this change, java.lang.ThreadDeath has been deprecated for removal.

Improved Control of G1 Concurrent Refinement Threads (JDK-8137022)

hotspot/gc

The control of G1 concurrent refinement threads has been completely replaced. The new controller typically allocates fewer threads. It tends to have fewer spikes in refinement thread activity. It also tends to delay refinement, allowing more filtering by the write barrier when there are multiple writes to the same or nearby locations, improving the efficiency of the barrier.

There are a number of command line options used to provide parameter values for the old controller. These aren't relevant to the new controller, and no longer serve any useful purpose. They have all been made obsolete; specifying any of them on the command line will do nothing but print a warning message about the option being obsolete. These arguments are:

-XX:-G1UseAdaptiveConcRefinement

-XX:G1ConcRefinementGreenZone=buffer-count

-XX:G1ConcRefinementYellowZone=buffer-count

-XX:G1ConcRefinementRedZone=buffer-count

-XX:G1ConcRefinementThresholdStep=buffer-count

-XX:G1ConcRefinementServiceIntervalMillis=msec

These options will be removed entirely in some future release. Use of any of these options after that time will terminate startup of the virtual machine.

Remove Support for javac -source/-target/--release 7 (JDK-8173605)

tools/javac

Consistent with the policy outlined in JEP 182: Policy for Retiring javac -source and -target Options, support for the 7/1.7 argument value for javac's -source, -target, and --release flags has been removed.

Deprecated Features and Options

java.net.URL Constructors Are Deprecated (JDK-8294241)

core-libs/java.net

The java.net.URL constructors are deprecated in this release.

Developers are encouraged to use java.net.URI to parse or construct a URL. In cases where an instance of java.net.URL is needed to open a connection, java.net.URI can be used to construct or parse the URL string, possibly calling URI::parseServerAuthority() to validate that the authority component can be parsed as a server-based authority, and then calling URI::toURL() to create the URL instance.

A new method, URL::of(URI, URLStreamHandler) is provided for the advanced usages where there is a need to construct a URL with a given custom stream handler.

See the java.net.URL API documentation [1] for more details [2].

[1] https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/net/URL.html#constructor-summary

[2] https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/net/URL.html#constructor-deprecation

Deprecate JMX Management Applets for Removal (JDK-8297794)

core-svc/javax.management

The Java Management Extension (JMX) Management Applet (m-let) feature is deprecated for removal in a future release as it is irrelevant to modern applications - the deprecated public classes in javax.management.loading are: MLet, MLetContent, PrivateMLet, MLetMBean.

This will have no impact on the JMX agent used for local and remote monitoring, the built-in instrumentation of the Java virtual machine, or tooling that uses JMX.

Known Issues

java.lang.Float.floatToFloat16 and java.lang.Float.float16ToFloat May Return Different NaN Results when Optimized by the JIT Compiler (JDK-8302976, JDK-8289551, JDK-8289552)

hotspot/compiler

JDK 20 introduces two new methods which can be used to convert to and from the IEEE 754 binary16 format: java.lang.Float.floatToFloat16 and java.lang.Float.float16ToFloat.

The new methods may return different NaN results when optimized by the JIT compiler. To disable the JIT compiler optimization of these methods, the following command line options can be used:

-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_floatToFloat16,_float16ToFloat

JDK XSLT Transformer Limitations (JDK-8290347)

xml/jaxp

Applications using the JDK XSLT transformer to convert stylesheets to Java objects can encounter the following exception:

"com.sun.org.apache.xalan.internal.xsltc.compiler.util.InternalError: Internal XSLTC error: a method in the translet exceeds the Java Virtual Machine limitation on the length of a method of 64 kilobytes. This is usually caused by templates in a stylesheet that are very large. Try restructuring your stylesheet to use smaller templates."

Applications will encounter the above exception if the size of the XSL template is too large. It is recommended to split the XSL template into smaller templates. Alternatively, applications can override the JDK XSLT Transformer by providing third-party implementation JAR files in the class path.

Other Notes

Disabled TLS_ECDH_* Cipher Suites (JDK-8279164)

security-libs/javax.net.ssl

The TLS_ECDH_* cipher suites have been disabled by default, by adding "ECDH" to the jdk.tls.disabledAlgorithms security property in the java.security configuration file. The TLS_ECDH_* cipher suites do not preserve forward-secrecy and are rarely used in practice. Note that some TLS_ECDH_* cipher suites were already disabled because they use algorithms that are disabled, such as 3DES and RC4. This action disables the rest. Any attempts to use cipher suites starting with "TLS_ECDH_" will fail with an SSLHandshakeException. Users can, at their own risk, re-enable these cipher suites by removing "ECDH" from the jdk.tls.disabledAlgorithms security property.

Disabled DTLS 1.0 (JDK-8256660)

security-libs/javax.net.ssl

DTLS 1.0 has been disabled by default, by adding "DTLSv1.0" to the jdk.tls.disabledAlgorithms security property in the java.security configuration file. DTLS 1.0 has weakened over time and lacks support for stronger cipher suites. Any attempts to use DTLSv1.0 will fail with an SSLHandshakeException. Users can, at their own risk, re-enable the version by removing "DTLSv1.0" from the jdk.tls.disabledAlgorithms security property.

Restore Behavior of java.math.BigDecimal.movePointLeft() and movePointRight() on a Zero Argument (JDK-8289260)

core-libs/java.math

When these methods are invoked with a zero argument on a target with a negative scale, they return a result which is numerically the same as the target, but with a different unscaled value and scale.

In earlier releases, they returned a result with the same unscaled value and scale, which was against the specification.

The behavior is unchanged when the target has a non-negative scale or when the argument is not zero.

HTTP Response Input Streams Will Throw an IOException on Interrupt (JDK-8294047)

core-libs/java.net

HTTP Response Input Streams are InputStream instances returned by the ResponseSubscribers::ofInputStream method. In this release, the default implementation of their read method was changed to throw an IOException if the thread performing this operation is interrupted, instead of ignoring the interruption.

If the thread invoking the read operation is interrupted while blocking on read:

  • The request will be cancelled and the InputStream will be closed
  • The thread interrupt status will be set to true
  • An IOException will be thrown

HttpClient Default Keep Alive Time is 30 Seconds (JDK-8297030)

core-libs/java.net

In this release, the default idle connection timeout value for the HTTP/1.1 and HTTP/2 connections created by the java.net.http.HttpClient has been reduced from 1200 seconds to 30 seconds.

Idle Connection Timeouts for HTTP/2 (JDK-8288717)

core-libs/java.net

Idle Connection Timeouts for HTTP/2 are added in this release.

The jdk.httpclient.keepalivetimeout property can now be used to configure a system-wide value, in seconds, used to close idle connections for both HTTP/1.1 and HTTP/2 when using the HttpClient. In addition, developer's can also use the jdk.httpclient.keepalivetimeout.h2 to specify a timeout value exclusively for use with the HTTP/2 protocol, regardless of whether or not the jdk.httpclient.keepalivetimeout` is specified at runtime.

See the java.net.http module and Networking Properties in the JDK 20 API documentation for a list of current networking properties.

URL Constructors Called with Malformed Input May Throw MalformedURLException for Cases where It Was Not Thrown Previously (JDK-8293590)

core-libs/java.net

The parsing of input provided to the java.net.URL constructors has changed in this release to be more strict. If the URL constructors are called with malformed input, then MalformedURLException may be thrown for cases where it wasn’t thrown previously.

In previous releases, some of the parsing and validation performed by the JDK built-in URLStreamHander implementations was delayed until URL::openConnection or URLConnection::connect was called. Some of these parsing and validation actions are now performed early, within URL constructors. An exception caused by a malformed URL that would have been delayed until the connection was opened or connected might now cause a MalformedURLException to be thrown at URL construction time.

This change only affects URL instances that delegate to JDK built-in stream handler implementations. Applications relying on custom, third party URLStreamHandler implementations should remain unaffected.

A new JDK specific system property -Djdk.net.url.delayParsing or -Djdk.net.url.delayParsing=true can be specified on the command line to revert to the previous behavior. By default, the property is not set, and the new behavior is in place.

This new property is provided for backward compatibility and may be removed in a future release.

Do Not Normalize File Paths to Unicode Normalization Format D on macOS (JDK-8289689)

core-libs/java.nio

On macOS, file names are no longer normalized to Apple's variant of Unicode Normalization Format D. File names were normalized on HFS+ prior to macOS 10.13, but on APFS on macOS 10.13 and newer, this normalization is no longer effected. The previous behavior may be enabled by setting the system property "jdk.nio.path.useNormalizationFormD" to "true".

FileChannel Positional Write Is Unspecified in APPEND Mode (JDK-6924219)

core-libs/java.nio

The specification of java.nio.channels.FileChannel is updated to clarify that the effect of attempting to write at a specific position using the FileChannel::write(ByteBuffer,long) method is system-dependent when the channel is open in append mode. That is, a java.nio.file.StandardOpenOption.APPEND is passed to FileChannel::open when the channel is opened. In particular, on some operating systems, bytes will be written at the given position, while on other operating systems the given position will be ignored and the bytes will be appended to the file.

Grapheme Support in BreakIterator (JDK-8291660)

core-libs/java.text

Character boundary analysis in java.text.BreakIterator now conforms to Extended Grapheme Clusters breaks defined in Unicode Consortium's Standard Annex #29. This change will introduce intentional behavioral changes because the old implementation simply breaks at the code point boundaries for the vast majority of characters. For example, this is a String that contains the US flag and a grapheme for a 4-member-family.

"🇺🇸👨‍👩‍👧‍👦"

This String will be broken into two graphemes with the new implementation:

"🇺🇸", "👨‍👩‍👧‍👦"

whereas the old implementation simply breaks at the code point boundaries:

"🇺", "🇸", "👨", "(zwj)", "👩", "(zwj)", "👧", "(zwj)"‍, "👦" 

where (zwj) denotes ZERO WIDTH JOINER (U+200D).

Update Timezone Data to 2022c (JDK-8292579)

core-libs/java.time

This version includes changes from 2022b that merged multiple regions that have the same timestamp data post-1970 into a single time zone database. All time zone IDs remain the same but the merged time zones will point to a shared zone database.

As a result, pre-1970 data may not be compatible with earlier JDK versions. The affected zones are Antarctica/Vostok, Asia/Brunei, Asia/Kuala_Lumpur, Atlantic/Reykjavik, Europe/Amsterdam, Europe/Copenhagen, Europe/Luxembourg, Europe/Monaco, Europe/Oslo, Europe/Stockholm, Indian/Christmas, Indian/Cocos, Indian/Kerguelen, Indian/Mahe, Indian/Reunion, Pacific/Chuuk, Pacific/Funafuti, Pacific/Majuro, Pacific/Pohnpei, Pacific/Wake, Pacific/Wallis, Arctic/Longyearbyen, Atlantic/Jan_Mayen, Iceland, Pacific/Ponape, Pacific/Truk, and Pacific/Yap.

For more details, refer to the announcement of 2022b

Weaken the InflaterInputStream Specification in Order to Allow Faster Zip Implementations (JDK-8282648)

core-libs/java.util.jar

The specification of the read methods defined by java.util.zip.InflaterInputStream,ZipInputStream, and GZIPInputStream have changed to allow these methods deviate from InputStream.read for the case that a “short read” occurs.

A “short read” is the case where the user provides a buffer with space for M bytes but only N bytes (where 0 < N < M) are read. The long standing specification for InputStream.read is that N bytes are stored in the buffer provided by the user and elements at offset off+N to off+M-1 are not changed.

The deviation allows the read method to use the elements at off+N to off+M-1 as temporary storage. Code using these APIs can no longer depend on these elements being unaffected when reading uncompressed data into a byte array.

IdentityHashMap's Remove and Replace Methods Use Object Identity (JDK-8178355)

core-libs/java.util:collections

The remove(key, value) and replace(key, oldValue, newValue) implementations of IdentityHashMap have been corrected. In previous releases, the value arguments were compared with values in the map using equals. However, IdentityHashMap specifies that all such comparisons should be made using object identity (==). These methods' implementations now conform to the specification.

Support for CLDR Version 42 (JDK-8284840)

core-libs/java.util:i18n

Locale data based on Unicode Consortium's CLDR has been upgraded to version 42. For the detailed locale data changes, please refer to the Unicode Consortium's CLDR release notes. Some of the notable changes in the upstream that may affect formatting are:

Introduce LDAP and RMI Protocol Specific Object Factory Filters to JNDI Implementation (JDK-8290368)

core-libs/javax.naming

In this release, new system and security properties are introduced to allow more granular control over the set of JNDI object factories allowed to reconstruct Java objects from JNDI/LDAP and JNDI/RMI contexts:

  • The new jdk.jndi.ldap.object.factoriesFilter property specifies which object factory classes are allowed to instantiate Java objects from object references returned by JNDI/LDAP contexts. Its default value only allows object factories defined in the java.naming module.

  • The new jdk.jndi.rmi.object.factoriesFilter property specifies which object factory classes are allowed to instantiate Java objects from object references returned by JNDI/RMI contexts. Its default value only allows object factories defined in the jdk.rmi module.

These new factory filter properties complement the jdk.jndi.object.factoriesFilter global factories filter property by determining if a specific object factory is permitted to instantiate objects for the LDAP or RMI protocols used in JNDI.

An application depending on custom object factories to recreate Java objects from JNDI/LDAP or JNDI/RMI contexts will need to supply a security or system property with an updated value to allow such third-party object factories to reconstruct LDAP or RMI objects. If usage of a factory is denied, the lookup operation may result in a plain instance of javax.naming.Reference instance returned, which may lead to a ClassCastException being thrown in the application.

For more information, see the java.naming and jdk.naming.rmi module-info documentation.

Update Default Value and Extend the Scope of com.sun.jndi.ldap.object.trustSerialData System Property (JDK-8290367)

core-libs/javax.naming

In this release, the JDK implementation of the LDAP provider no longer supports deserialization of Java objects by default:

  • The default value of the com.sun.jndi.ldap.object.trustSerialData system property has been updated to false.

  • The scope of the com.sun.jndi.ldap.object.trustSerialData system property has been extended to cover the reconstruction of RMI remote objects from the javaRemoteLocation LDAP attribute.

The transparent deserialization of Java objects from an LDAP context will now require an explicit opt-in. Applications that rely on reconstruction of Java objects or RMI stubs from the LDAP attributes would need to set the com.sun.jndi.ldap.object.trustSerialData system property to true.

com.sun.jdi.ObjectReference::setValue Specification Should Prohibit Any Final Field Modification (JDK-8280798)

core-svc/debugger

The specification of the Java Debug Interface (JDI) method ObjectReference.setValue has changed in this release to require the given field be non-final. The method was previously specified to require static fields be non-final but was silent on final instance fields. The JDK’s implementation of JDI has never allowed final instance fields to be changed with this method so this change has no impact on debuggers or tools using the JDK’s JDI implementation. Maintainers of JDI implementations should take note of this change so they can align their implementation with the updated specification.

JMX Connections Use an ObjectInputFilter by Default (JDK-8283093)

core-svc/javax.management

The default JMX agent now sets an ObjectInputFilter on the RMI connection to restrict the types that the server will deserialize. This should not affect normal usage of the MBeans in the JDK. Applications which register their own MBeans in the Platform MBeanServer may need to extend the filter to support any additional types that their MBeans accept as parameters. The default filter already covers any type that OpenMBeans and MXBeans might use.

The filter pattern is set in JDK/conf/management/management.properties using the property com.sun.management.jmxremote.serial.filter.pattern. If there are additional Java types that need to be passed, the default can be overridden by running with -Dcom.sun.management.jmxremote.serial.filter.pattern=.

Serialization Filtering and the filter pattern format are described in detail in the Core Libraries guide.

G1: Disable Preventive GCs by Default (JDK-8293861)

hotspot/gc

In JDK 17, G1 added "preventive" garbage collections (GCs). These are speculative garbage collections, with the goal of avoiding costly evacuation failures due to allocation bursts when the heap is almost full.

However, these speculative collections have the consequence of additional garbage collection work, as object aging is based on number of GCs with additional GCs causing premature promotion into the old generation, which leads to more data in the old generation, and more garbage collection work to remove these objects. This has been compounded by the current prediction to trigger preventive garbage collections being very conservative; which means these garbage collections are often triggered unnecessarily.

In the majority of cases this feature is a net loss, and as evacuation failures are now handled more quickly, there is no longer any reason for this feature and it has been disabled by default, it may be re-enabled by -XX:+UnlockDiagnosticVMOptions -XX:+G1UsePreventiveGC.

appendToClassPathForInstrumentation Must Be Used in a Thread-Safe Manner (JDK-8296472)

hotspot/jvmti

When running an application with a Java agent (e.g. -javaagent:myagent.jar) and a custom system class loader (e.g. -Djava.system.class.loader=MyClassLoader), and the Java agent invokes the Instrumentation.appendToSystemClassLoaderSearch API to append to the class loader search, then the custom system class loader appendToClassPathForInstrumentation method will be invoked to add the JAR file to the custom system class loader's search path.

The JVM no longer synchronizes on the custom class loader while calling appendToClassPathForInstrumentation. The appendToClassPathForInstrumentation method in the custom class loader must add to the class search path in a thread-safe manner.

GetLocalXXX/SetLocalXXX Specification Should Require Suspending Target Thread (JDK-8288387)

hotspot/jvmti

The JVM TI specification of the GetLocalXXX/SetLocalXXX functions has been changed to require the target thread to be either suspended or the current thread. The error code JVMTI_ERROR_THREAD_NOT_SUSPENDED will be returned if this requirement is not satisfied. The JVM TI agents which use the GetLocalXXX/SetLocalXXX API's need to be updated to suspend the target thread if it is not the current thread. The full list of impacted JVM TI functions is:

  • GetLocalObject, GetLocalInt, GetLocalLong, GetLocalFloat, GetLocalDouble, GetLocalInstance,
  • SetLocalObject, SetLocalInt, SetLocalLong, SetLocalFloat, SetLocalDouble

The JNI Specification Omits an Update to the JNI Version (JDK-8290482)

hotspot/runtime

This bug updated the JNI Specification in relation to the DestroyJavaVM function. As part of that work, the JNI Specification version number was incremented. That change to the JNI Specification version should also have been reflected in the GetVersion function but was not. The GetVersion function for Java SE 20 and later has been updated to read JNI_VERSION_20.

This new version has also been documented in jni.h as:

#define JNI_VERSION_20  0x00140000

Deprecate and Disable Legacy Parallel Class Loading Workaround for Non-Parallel-Capable Class Loaders (JDK-8295673)

hotspot/runtime

Some user-defined, older class loaders would workaround a deadlock issue by releasing the class loader lock during the loading process. To prevent these loaders from encountering a “java.lang.LinkageError: attempted duplicate class definition” while loading the same class by parallel threads, the HotSpot Virtual Machine introduced a workaround in JDK 6 that serialized the load attempts, causing the subsequent attempts to wait for the first to complete.

The need for class loaders to work this way was removed in JDK 7 when parallel-capable class loaders were introduced, but the workaround remained in the VM. That workaround is finally being removed and as a first step has been deprecated and disabled by default. If you start seeing "java.lang.LinkageError: attempted duplicate class definition", then you may have an affected legacy class loader. The flag -XX:+EnableWaitForParallelLoad can be used to temporarily restore the old behavior in this release of the JDK, but the legacy class loader will need to be updated for future releases.

See the CSR request (JDK-8295848) for more background and details.

Added Constructors (String, Throwable) and (Throwable) to InvalidParameterException (JDK-8296226)

security-libs/java.security

Constructors InvalidParameterException(String, Throwable) and InvalidParameterException(Throwable) have been added to the java.security.InvalidParameterException class to support easy construction of InvalidParameterException objects with a cause.

Throw Error If Default java.security File Fails to Load (JDK-8155246)

security-libs/java.security

A behavioral change has been made in the case where the default conf/security/java.security security configuration file fails to load. In such a scenario, the JDK will now throw an InternalError.

Such a scenario should never occur. The default security file should always be present. Prior to this change, a static security configuration was loaded.

Remove Thread Text from Subject.current (JDK-8297276)

security-libs/javax.security

The specification of Subject.current has been changed in this release to drop the expectation that the Subject is inherited when creating a thread. At this time, the Subject is stored in the AccessControlContext and is inherited when creating platform threads. Virtual threads do not capture the caller context at thread creation time and the AccessControlContext is not inherited. Inheritance will be re-examined in a future release in advance of removing support for the SecurityManager and the inherited AccessControlContext.

New Implementation Note for LoginModule on Removing Null from a Principals or Credentials Set (JDK-8282730)

security-libs/javax.security

The Set implementation that holds principals and credentials in a JAAS Subject prohibits null elements and any attempt to add, query, or remove a null element will result in a NullPointerException. This is especially important when trying to remove principals or credentials from the subject at the logout phase but they are null because of a previous failed login. Various JDK LoginModule implementations have been fixed to avoid the exception. An Implementation Note has also been added to the logout() method of the LoginModule interface. Developers should verify, and if necessary update, any custom LoginModule implementations to be compliant with this implementation advice.

An Exhaustive Switch over an Enum Class Should Throw MatchException Rather Than IncompatibleClassChangeError If No Switch Label Applies at Runtime (JDK-8297118)

tools/javac

In this release, when preview features are enabled with --enable-preview, a switch expression over an enum type will throw a MatchException rather than an IncompatibleClassChangeError should the selector expression yield an unexpected enum constant value. This can only happen if the enum class has been changed by adding a new enum constant after compilation of the switch.

This change is required to unify the treatment of erroneous exhaustive switches introduced by enhancing switch with pattern labels.

Improved Preview API Page (JDK-8287597)

tools/javadoc(tool)

The Preview API page in the documentation generated by JavaDoc now provides detailed information about the JEPs the preview features belong to.

Generalize see and link Tags for User-Defined Anchors (JDK-8200337)

tools/javadoc(tool)

The {@link}, {@linkplain} and @see tags have been enhanced to allow linking to arbitrary anchors in the JavaDoc-generated documentation for an element. To distinguish these references from member references, a double hash mark (##) is used to separate the element name from the URI fragment.

Auto-Generated IDs in JavaDoc Headings (JDK-8289332)

tools/javadoc(tool)

JavaDoc now generates id attributes for all HTML headings in documentation comments that may be used as link anchors.