JDK 19 Early-Access Release Notes

This is a draft of the release notes that will accompany JDK 19. The contents are subject to change until release.

Build 24

Removal of diagnostic flag GCParallelVerificationEnabled (JDK-8286304)


The diagnostic flag GCParallelVerificationEnabled has been removed.

There are no known advantages of disabling parallel heap verification, so this flag has never been used except with its default value. This default value enabled multi-threaded verification for a very long time with no issues. Single-threaded heap verification would even be much slower than verification already is.

Build 23

Lambda deserialization fails for Object method references on interfaces (JDK-8282080)


Deserialization of serialized method references to Object methods, which was using an interface as the type on which the method is invoked, can now be deserialized again. Note the classfiles need to be recompiled to allow the deserialization.

Build 22

Remove finalizer implementation in SSLSocketImpl (JDK-8212136)


The finalizer implementation in SSLSocket has been removed in JDK, with the underlying native resource releases done by the Socket implementation. With this update, the TLS close_notify messages will no longer be emitted if SSLSocket is not explicitly closed.

Not closing Sockets properly is an error condition that should be avoided. Applications should always close sockets and not rely on garbage collection.

java.lang.ThreadGroup is degraded (JDK-8284161)


Legacy java.lang.ThreadGroup has been degraded in this release. It is no longer possible to explicitly destroy a thread group. In its place, ThreadGroup is changed to no longer keep a strong reference to subgroups. A thread group is thus eligible to be GC'ed when there are no live threads in the group and nothing else is keeping the thread group alive.

The behavior of several methods, deprecated for removal in prior releases, are changed as follows:

  • The destroy method does nothing.

  • The isDestroyed method returns false.

  • The setDaemon and isDaemon methods set/get a daemon status that is not used for anything.

  • The suspend, resume, and stop methods throw UnsupportedOperationException.

For further details, see the JEP 425, section java.lang.ThreadGroup.

JEP 425: Virtual Threads (Preview) (JDK-8284161)


Virtual threads have been added to the Java Platform as a preview feature. Virtual threads are lightweight threads that are scheduled by the Java runtime rather than the operating system. Virtual threads reduce the effort of developing, maintaining, and observing high-throughput concurrent applications.

For further details, see JEP 425.

Build 21

RPM JDK installer changes (JDK-8275446)

Installation directory name of Oracle JDK in RPM package has changed from /usr/java/jdk-${VERSION} to /usr/lib/jvm/jdk-${FEATURE}-oracle-${ARCH}. Thus the 19.0.1 and 19.0.2 releases for x64 will both be installed in /usr/lib/jvm/jdk-19-oracle-x64 directory. RPM package will create /usr/java/jdk-${FEATURE} link pointing to the installation directory for backward compatibility.

Communication with the alternatives framework of JDK RPM package has changed. JDK RPM packages of prior versions registered a single java group of commands with the alternatives framework. The JDK 19 RPM package registers java and javac groups with the alternatives framework. java group is for commands used to run applications: java, keytool, and rmiregistry. javac group is used for all other commands. The set of commands registered by the package has not changed.

JDK-8278370: [win] Disable side-by-side installations of multiple JDK updates in Windows JDK installers (JDK-8278370)


Windows JDK installers must install the Oracle JDK in %Program Files%Javajdk-%FEATURE% instead of %Program Files%Javajdk-%VNUM%. I.e. all updates of the same release must share one installation directory.

Thus the 19.0.1 and 19.0.2 releases will both install into %Program Files%Javajdk-19 by default, and they both cannot be installed at the same time.

If the JDK19.0.2 installer is launched when JDK19.0.1 is already installed, it will auto-upgrade them to JDK19.0.2. There may be a Files In Use dialog shown if the older version was running and locking JDK files.

If the JDK19.0.1 installer is launched when JDK19.0.2 is already installed, it will show an error that a newer version of this JDK family is already installed.

All JDK updates releases are installed into the same directory on macOS (JDK-8281010)


The Oracle JDK installation directory name will be changed from /Library/Java/JavaVirtualMachines/jdk-${VERSION}.jdk to /Library/Java/JavaVirtualMachines/jdk-${FEATURE}.jdk. Thus the 19.0.1 and 19.0.2 releases will both install into the /Library/Java/JavaVirtualMachines/jdk-19.jdk installation directory. Installing an older JDK update release will log an error, and not install the JDK, if a newer version of the same feature release already exists. An error dialog will be shown except in the case of a silent installation.

Build 20

Enable Windows Alternate Data Streams by default (JDK-8285445)


The Windows implementation of java.io.File has been changed so that strict validity checks are not performed by default on file paths. This includes allowing colons (‘:’) in the path other than only immediately after a single drive letter. It also allows paths that represent NTFS Alternate Data Streams (ADS), such as “filename:streamname”. This restores the default behavior of java.io.File to what it was prior to the April 2022 CPU in which strict validity checks were not performed by default on file paths on Windows. To re-enable strict path checking in java.io.File, the system property jdk.io.File.enableADS should be set to false (case ignored). This might be preferable, for example, if Windows special device paths such as NUL: are not used.

New system properties for System.out and System.err (JDK-8283620)


Two new system properties, stdout.encoding and stderr.encoding, have been added. The value of these system properties is the encoding used by the standard output and standard error streams (System.out and System.err).

The default values of these system properties depend on the platform. The values take on the value of the native.encoding property when the platform does not provide streams for the console. The properties can be overridden on the launcher's command line option (with -D) to set them to UTF-8 where required.

Build 19

New Methods to Create Preallocated HashMaps (JDK-8186958)


A new static factory method has been introduced that allows creation of HashMap instances that are preallocated to contain an expected number of mappings. After using this method, the new HashMap can accommodate the expected number of mappings without being resized. Similarly, there are also new static factory methods for LinkedHashMap and WeakHashMap. The methods are:

  • HashMap.newHashMap
  • LinkedHashMap.newLinkedHashMap
  • WeakHashMap.newWeakHashMap

The int-bearing constructors for these classes set the "capacity" (internal table size) which is not the same as the number of mappings that can be accommodated. The capacity is related to the number of mappings by a simple but error-prone calculation. For this reason, programs should use these new static factory methods in preference to the int-bearing constructors.

Build 18

Metal is now the default Java 2D rendering pipeline on macOS (JDK-8284378)


Previously JDK desktop applications using Swing and Java2D (tm) would render using OpenGL on macOS. As of this release of JDK, they now are rendered using Apple's new Metal accelerated graphics API. This has been available since JDK 17 (JEP 382), but was not automatically enabled. Now it is enabled by default. Applications will not need to take any action, as they will automatically benefit from faster graphics with lower power consumption, and the use of a more modern stable graphics API which will be able to work better on current and future Apple Mac systems. Any user who would prefer to continue to use OpenGL whilst it is still supported can disable rendering with Metal by starting their application with either "java -Dsun.java2d.metal=false" or "java -Dsun.java2d.opengl=true" and it will run with OpenGL as it used to in JDK 17.

Build 17

Deprecation of Locale class constructors (JDK-8282819)


New Locale.of() factory methods replace deprecated Locale constructors. The factory methods are efficient and reuse existing Locale instances. Locales are also provided by Locale.forLanguageTag() and Locale.Builder.

Build 16

TLS Cipher Suites using 3DES Removed from the Default Enabled List (JDK-8163327)


The following TLS cipher suites that use the obsolete 3DES algorithm have been removed from the default list of enabled cipher suites:


Note that cipher suites using 3DES are already disabled by default in the jdk.tls.disabledAlgorithms security property. You may use these suites at your own risk by removing 3DES_EDE_CBC from the jdk.tls.disabledAlgorithms security property and re-enabling the suites via the setEnabledCipherSuites() method of the SSLSocket, SSLServerSocket or SSLEngine classes. Alternatively, if an application is using the HttpsURLConnection class, the https.cipherSuites system property can be used to re-enable the suites.

Build 14

(D)TLS signature schemes (JDK-8280494)


New Java SE APIs, javax.net.ssl.getSignatureSchemes() and javax.net.ssl.setSignatureSchemes(), have been added to allow applications to customize the signature schemes used in individual TLS or DTLS connections.

Note that the underlying provider may define the default signature schemes for each TLS or DTLS connection. Applications may also use the existing "jdk.tls.client.SignatureSchemes" and/or "jdk.tls.server.SignatureSchemes" system properties to customize the provider-specific default signature schemes. If not null, the signature schemes passed to the setSignatureSchemes() method will override the default signature schemes 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 signature schemes that are set. The JDK SunJSSE provider supports this method. It is recommended that 3rd party providers add support for these methods when they add support for JDK 19 or later releases.

Build 13

java.time.DateTimeFormatter: wrong definition of symbol F (JDK-8282081)


The definition and its implementation of the pattern symbol F in java.time.format.DateTimeFormatter/Builder has been modified. It was tied with ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH field, which did not agree with java.text.SimpleDateFormat and Unicode Consortium's LDML. With this release, it represents ChronoField.ALIGNED_WEEK_OF_MONTH field. For example, the number 2 means "the 2nd Wednesday in July."

Build 12

If the users home directory is invalid, system property user.home is set to $HOME (JDK-8280357)


On Linux and macOS, the system property user.home is set to the home directory provided by the operating system. If the directory name provided is empty or only a single character, the value of the environment variable HOME is used instead.

The directory name and the value of $HOME are usually the same and valid. The fallback to $HOME is unusual and unlikely to occur except in environments such as systemd on Linux or when running in a container such as Docker.

Break up SEQUENCE in X509Certificate::getSubjectAlternativeNames and X509Certificate::getIssuerAlternativeNames in otherName (JDK-8277976)


The JDK implementation of X509Certificate::getSubjectAlternativeNames and X509Certificate::getIssuerAlternativeNames has been enhanced to additionally return the type-id and value fields of an otherName. The value field is returned as a String if it is encoded as a character string or otherwise as a byte array, which is helpful as it avoids having to parse the ASN.1 DER encoded form of the name.

Support for PAC-RET Protection on Linux/AArch64 (JDK-8277204)


Support for PAC-RET protection on the Linux/AArch64 platform has been introduced.

When enabled, OpenJDK will use hardware features from the ARMv8.3 Pointer Authentication Code (PAC) extension to protect against Return Orientated Programming (ROP) attacks. For more information on the PAC extension see "Providing protection for complex software" or the "Pointer authentication in AArch64 state" section in the Arm ARM.

To take advantage of this feature, first OpenJDK must be built with the configuration flag --enable-branch-protection using GCC 9.1.0+ or LLVM 10+ . Then, the runtime flag -XX:UseBranchProtection=standard will enable PAC-RET protection if the system supports it and the java binary was compiled with branch-protection enabled; otherwise the flag is silently ignored. Alternatively, -XX:UseBranchProtection=pac-ret will also enable PAC-RET protection, but in this case if the system does not support it or the java binary was not compiled with branch-protection enabled, then a warning will be printed.

Build 11

Additional Date-Time Formats (JDK-8176706)


Additional date/time formats are now introduced in java.time.format.DateTimeFormatter/DateTimeFormatterBuilder classes. In prior releases, only 4 predefined styles, i.e., FormatStyle.FULL/LONG/MEDIUM/SHORT are available. Now the users can specify their own flexible style with this new DateTimeFormatter.ofLocalizedPattern(String requestedTemplate) method. For example,


produces a formatter, which can format a date in a localized manner, such as "Feb 2022" in the US locale, while "2022年2月" in the Japanese locale. Supporting method DateTimeFormatterBuilder.appendLocalized(String requestedTemplate)is also provided.

Build 9

Add a -providerPath option to jarsigner (JDK-8281175)


A new option -providerPath has been added to jarsigner. One can use this option to specify the class path of an alternate keystore implementation. It can be used together with the -providerClass option.

Build 8

HTTPS Channel Binding support for Java GSS/Kerberos (JDK-8279842)


Support has been added for TLS channel binding tokens for Negotiate/Kerberos authentication over HTTPS through javax.net.HttpsURLConnection.

Channel binding tokens are increasingly required as an enhanced form of security which can mitigate certain kinds of socially engineered, man in the middle (MITM) attacks. They work by communicating from a client to a server the client's understanding of the binding between connection security (as represented by a TLS server cert) and higher level authentication credentials (such as a username and password). The server can then detect if the client has been fooled by a MITM and shutdown the session/connection.

The feature is controlled through a new system property jdk.https.negotiate.cbt which is described fully at the following page: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/net/doc-files/net-properties.html#jdk.https.negotiate.cbt

Build 6

New options for ktab to provide non-default salt (JDK-8279064)


Two new options are added to the ktab command when adding new keytab entries. When ktab -a username password -s altsalt is called, altsalt is used instead of the default salt. When ktab -a username password -f is called, the tool will contact the KDC to fetch the actual salt used.

Build 5

Indy string concat changes order of operations (JDK-8273914)


String concatenation has been changed to evaluate each argument and eagerly convert it to a string, in left-to-right order. This fixes a bug in the invokedynamic-based string concatentation strategies introduced in JEP 280.

For example, the following now prints "foofoobar", not "foobarfoobar":

    StringBuilder builder = new StringBuilder("foo");
    System.err.println("" + builder + builder.append("bar"));

Support Unicode 14.0 (JDK-8268081)


This release upgrades Unicode support to 14.0, which includes the following:

The java.lang.Character class supports Unicode Character Database of 14.0 level, which adds 838 characters, for a total of 144,697 characters. These additions include 5 new scripts, for a total of 159 scripts, as well as 37 new emoji characters. The java.text.Bidi and java.text.Normalizer classes support 14.0 level of Unicode Standard Annexes, #9 and #15, respectively. The java.util.regex package supports Extended Grapheme Clusters based on 14.0 level of Unicode Standard Annex #29 For more detail about Unicode 14.0, refer to the Unicode Consortium's release note.


Only Expose Certificates With Proper Trust Settings as Trusted Certificate Entries in macOS KeychainStore (JDK-8278449)


On macOS, only certificates with proper trust settings in the user keychain will be exposed as trusted certificate entries in the KeychainStore type of keystore. Also, calling the KeyStore::setCertificateEntry method or the keytool -importcert command on a KeychainStore keystore now fails with a KeyStoreException. Instead, call the macOS "security add-trusted-cert" command to add a trusted certificate into the user keychain.

Parsing of URL Strings in Built-in JNDI Providers Is More Strict (JDK-8278972)


The parsing of URLs in the LDAP, DNS, and RMI built-in JNDI providers has been made more strict. The strength of the parsing can be controlled by system properties:

  -Dcom.sun.jndi.ldapURLParsing="legacy" | "compat" | "strict"    (to control "ldap:" URLs)
  -Dcom.sun.jndi.dnsURLParsing="legacy" | "compat" | "strict"     (to control "dns:" URLs)
  -Dcom.sun.jndi.rmiURLParsing="legacy" | "compat" | "strict"     (to control "rmi:" URLs)

The default value is "compat" for all of the three providers.

  • The "legacy" mode turns the new validation off.
  • The "compat" mode limits incompatibilities.
  • The "strict" mode is stricter and may cause regression by rejecting URLs that an application might consider as valid.

In "compat" and "strict" mode, more validation is performed. As an example, in the URL authority component, the new parsing only accepts brackets around IPv6 literal addresses. Developers are encouraged to use java.net.URI constructors or its factory method to build URLs rather than handcrafting URL strings.

If an illegal URL string is found, a java.lang.IllegalArgumentException or a javax.naming.NamingException (or a subclass of it) is raised.

New XML Processing Limits (JDK-8270504)


Three processing limits have been added to the XML libraries. These are:

  • jdk.xml.xpathExprGrpLimit

Description: Limits the number of groups an XPath expression can contain.

Type: integer

Value: A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumberFormatException is thrown. Default 10.

  • jdk.xml.xpathExprOpLimit

Description: Limits the number of operators an XPath expression can contain.

Type: integer

Value: A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumberFormatException is thrown. Default 100.

  • jdk.xml.xpathTotalOpLimit

Description: Limits the total number of XPath operators in an XSL Stylesheet.

Type: integer

Value: A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumberFormatException is thrown. Default 10000.

Supported processors

  • jdk.xml.xpathExprGrpLimit and jdk.xml.xpathExprOpLimit are supported by the XPath processor.

  • All three limits are supported by the XSLT processor.

Setting properties

For the XSLT processor, the properties can be changed through the TransformerFactory. For example,

        TransformerFactory factory = TransformerFactory.newInstance();
        factory.setAttribute("jdk.xml.xpathTotalOpLimit", "1000");

For the XPath processor, the properties can be changed through the XPathFactory. For example,

        XPathFactory xf = XPathFactory.newInstance();
        xf.setProperty("jdk.xml.xpathExprGrpLimit", "20");

For both the XPath and XSLT processors, the properties can be set through the system property and jaxp.properties configuration file located in the conf directory of the Java installation. For example,

        System.setProperty("jdk.xml.xpathExprGrpLimit", "20");

or in the jaxp.properties file,


There are two known issues:

  1. An XPath expression that contains a short form of the parent axis ".." can return incorrect results. See JDK-8284920 for details.

  2. An invalid XPath expression that ends with a relational operator such as ‘<’ ‘>’ and ‘=’ will cause the processor to erroneously throw StringIndexOutOfBoundsException instead of XPathExpressionException. See JDK-8284548 for details.