JDK 22 Release Notes

Publication Date: 19 March 2024

The following sections are included in these Release Notes:


Java™ SE Development Kit 22

These notes describe important changes, enhancements, removed APIs and features, deprecated APIs and features, and other information about JDK 22 and Java SE 22. 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 22 ( JSR 397) 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 22 ( JSR 397) specification provides links to:

You should be aware of the content in the Java SE 22 ( JSR 397) specification as well as the items described in this page.

The descriptions on this Release Notes page also identify potential compatibility issues that you might encounter when migrating to JDK 22. The Kinds of Compatibility page on the OpenJDK wiki identifies the following three types of potential compatibility issues for Java programs that might be used in these release notes:

  • 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.

See CSRs Approved for JDK 22 for the list of CSRs closed in JDK 22 and the Compatibility & Specification Review (CSR) page on the OpenJDK wiki for general information about compatibility.

The full version string for this release is build 22+36 (where "+" means "build"). The version number is 22.

IANA Data 2023d

JDK 22 contains IANA time zone data version 2023d. For more information, refer to Timezone Data Versions in Java Runtimes.

 

TOP


Major New Functionality

 

1. Language

 Unnamed Variables & Patterns

Enhance the Java programming language with unnamed variables and unnamed patterns, which can be used when variable declarations or nested patterns are required but never used. Both are denoted by the underscore character, _.

See JEP 456

 

1.1 Language Previews

 Statements before super(...) (Preview)

In constructors in the Java programming language, allow statements that do not reference the instance being created to appear before an explicit constructor invocation. This is a preview language feature.

See JEP 447

 

 Stream Gatherers (Preview)

Enhance the Stream API to support custom intermediate operations. This will allow stream pipelines to transform data in ways that are not easily achievable with the existing built-in intermediate operations. This is a preview API.

See JEP 461

 

 String Templates (Second Preview)

Enhance the Java programming language with string templates. String templates complement Java's existing string literals and text blocks by coupling literal text with embedded expressions and template processors to produce specialized results. This is a preview language feature and API.

See JEP 459

 

 Implicitly Declared Classes and Instance Main Methods (Second Preview)

Evolve the Java programming language so that students can write their first programs without needing to understand language features designed for large programs. Far from using a separate dialect of the language, students can write streamlined declarations for single-class programs and then seamlessly expand their programs to use more advanced features as their skills grow. This is a preview language feature.

See JEP 463

 

2. Libraries

 Foreign Function & Memory API

Introduce an API by which Java programs can interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions (i.e., code outside the JVM), and by safely accessing foreign memory (i.e., memory not managed by the JVM), the API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI.

See JEP 454
See below for additional information

 

2.1 Library Previews and Incubator

 Class-File API (Preview)

Provide a standard API for parsing, generating, and transforming Java class files. This is a preview API.

See JEP 457

 

 Structured Concurrency (Second Preview)

Simplify concurrent programming by introducing an API for structured concurrency. Structured concurrency treats groups of related tasks running in different threads as a single unit of work, thereby streamlining error handling and cancellation, improving reliability, and enhancing observability. This is a preview API.

See JEP 462

 

 Scoped Values (Second Preview)

Introduce scoped values, which enable managed sharing of immutable data both with child frames in the same thread, and with child threads. Scoped values are easier to reason about than thread-local variables and have lower space and time costs, especially when used in combination with Virtual Threads and Structured Concurrency. This is a preview API.

See JEP 464

 

 Vector API (Seventh Incubator)

Introduce an API to express vector computations that reliably compile at runtime to optimal vector instructions on supported CPU architectures, thus achieving performance superior to equivalent scalar computations.

See JEP 460

 

3. Performance

 Region Pinning for G1

Reduce latency by implementing region pinning in G1, so that garbage collection need not be disabled during Java Native Interface (JNI) critical regions.

See JEP 423
See below for additional information

 

4. Tooling

 Launch Multi-File Source-Code Programs

Enhance the java application launcher to be able to run a program supplied as multiple files of Java source code. This will make the transition from small programs to larger ones more gradual, enabling developers to choose whether and when to go to the trouble of configuring a build tool.

See JEP 458

 

TOP


New Features

This section describes some of the enhancements in Java SE 22 and JDK 22. In some cases, the descriptions provide links to additional detailed information about an issue or a change. The APIs described here are provided with the Oracle JDK. It includes a complete implementation of the Java SE 22 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 22 and JDK 22 is the Java SE 22 ( JSR 397) Platform Specification, which documents the changes to the specification made between Java SE 21 and Java SE 22. 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 22.

core-libs/java.lang
 Support Unicode 15.1 (JDK-8296246)

This release upgrades the Unicode version to 15.1, which includes updated versions of the Unicode Character Database and Unicode Standard Annexes #9, #15, and #29:

  • The java.lang.Character class supports the Unicode Character Database, which adds 627 characters, for a total of 149,813 characters. The addition includes one new UnicodeBlock, which consists of urgently needed CJK ideographs, synchronized with planned additions to the Chinese national standard, GB 18030.
  • 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 details about Unicode 15.1, refer to the Unicode Consortium’s release note.

core-libs/java.lang.foreign
 Foreign Function & Memory API (JEP 454)

The Foreign Function & Memory API allows Java programs to interoperate with code and data outside of the Java runtime.

Access to foreign memory is realized via the MemorySegment class. A memory segment is backed by a contiguous region of memory, located either off-heap or on-heap. Safe and deterministic deallocation of off-heap memory segments is provided via the Arena class. Structured access to memory segments is realized via the MemoryLayout class. A memory layout can be used to compute the size and offsets of struct fields, and to obtain var handles that read and write the data in memory segments.

Access to foreign functions is realized via the Linker class. The native linker can be used to obtain method handles that provide a fast way for Java code to invoke native code. Native code is invoked using the calling convention for the OS and processor where the Java runtime is executing, so Java code is not polluted with platform-specific details. Native code can also call back into Java code.

Native code is generally unsafe; if used incorrectly, it might crash the JVM or result in memory corruption. Some of the methods in the Foreign Function & Memory API are considered unsafe because they provide access to native code. These unsafe methods are restricted, which means their use is permitted but causes warnings at run time. Developers can compile their code with -Xlint:restricted to learn if it will produce warnings at run time due to use of unsafe methods.

If the risks associated with native code are understood, then unsafe methods can be used without warnings at run time by passing --enable-native-access=... on the java command line. For example, java --enable-native-access=com.example.myapp,ALL-UNNAMED ... enables warning-free use of unsafe methods by code in the com.example.myapp module and code on the class path (denoted by ALL-UNNAMED). Additionally, in an executable JAR, the manifest attribute Enable-Native-Access: ALL-UNNAMED enables warning-free use of unsafe methods by code on the class path; no other module can be specified. When the --enable-native-access option or JAR manifest attribute is present, any use of unsafe methods by code outside the list of specified modules causes an IllegalCallerException to be thrown, rather than a warning to be issued.

core-libs/java.net
 TCP_KEEPxxxx Extended Socket Options Are Now Supported on the Windows Platform (JDK-8308593)

The java.net.ExtendedSocketOptions TCP_KEEPIDLE and TCP_KEEPINTERVAL are supported on Windows platforms starting from Windows 10 version 1709 and onwards. TCP_KEEPCOUNT is supported starting from Windows 10 version 1703 and onwards.

core-libs/java.nio.charsets
 New Constants for 32-bit UTF Charsets (JDK-8310047)

The following three new constants in java.nio.charset.StandardCharsets class have been introduced:

UTF_32

UTF_32BE
UTF_32LE

These are 32-bit based UTF charsets that are in parallel with the existing 8-bit and 16-bit equivalents.

core-libs/java.text
 Locale-Dependent List Patterns (JDK-8041488)

A new class, ListFormat, which processes the locale-dependent list patterns has been introduced, based on Unicode Consortium's LDML specification. For example, a list of three Strings: "Foo", "Bar", "Baz" is typically formatted as "Foo, Bar, and Baz" in US English, while in French it is "Foo, Bar et Baz." The following code snippet does such formatting:

ListFormat.getInstance().format(List.of("Foo", "Bar", "Baz"))

Besides the default concatenation type STANDARD (= and), the class provides two additional types, OR for "or" concatenation, and UNIT for concatenation suitable for units for the locale.

core-libs/java.util
 Add equiDoubles() Method to java.util.random.RandomGenerator. (JDK-8302987)

A new method, equiDoubles(), has been added to java.util.random.RandomGenerator.

equiDoubles() guarantees a uniform distribution, provided the underlying nextLong(long) method returns uniformly distributed values, that is as dense as possible. It returns a DoubleStream rather than individual doubles because of slightly expensive initial computations. They are better absorbed as setup costs for the stream rather than being repeated for each new computed value.

The aim is to overcome some numerical limitations in the families of doubles() and nextDouble() methods. In these, an affine transform is applied to a uniformly distributed pseudo-random value in the half-open interval [0.0, 1.0) to obtain a pseudo-random value in the half-open interval [origin, bound). However, due to the nature of floating-point arithmetic, the affine transform ends up in a slightly distorted distribution, which is not necessarily uniform.

hotspot/gc
 G1: Fast Collection of Evacuation Failed Regions (JDK-8140326)

G1 now reclaims regions that failed evacuation in the next garbage collection.

When there is not enough space to move Java objects from the collection set, young generation regions for example, to some destination area, or that region has been pinned and contains non-movable Java objects (see [JEP 423]), G1 considers that region to have failed evacuation.

Previously, such regions were moved into the old generation as completely full regions, and left lingering for re-examination until the next complete heap analysis, marking, found them to be reclaimable in the next space reclamation phase. Very often, such regions are sparsely populated because only a very few objects were not relocatable or very few objects were actually pinned.

With this change, G1 considers evacuation failed regions as reclaimable beginning with any subsequent garbage collection. If the pause time permits, G1 will evacuate them in addition to the existing collection set.

This can substantially reduce the time to reclaim these mostly empty regions, decreasing heap pressure and the need for garbage collection activity in the presence of evacuation failed regions.

hotspot/gc
 Parallel: Precise Parallel Scanning of Large Object Arrays for Young Collection Roots (JDK-8310031)

During young collection, ParallelGC partitions the old generation in 64kB stripes when scanning it for references into the young generation. These stripes are assigned to worker threads that do the scanning in parallel as work units.

Before this change Parallel GC always scanned these stripes completely even if only a small part had been known to contain interesting references. Additionally every worker thread processed the objects that start in that stripe by itself including any part of objects that extend into other stripes. This behavior limited parallelism when processing large objects: a single large object potentially containing thousands of references had been scanned by a single thread only and in full, and would also cause bad scaling due to memory sharing and cache misses in the subsequent long work stealing phase.

With this change, Parallel GC workers limit work to their stripe, and only process interesting parts of large object arrays. This reduces work done by a single thread for a stripe, improves parallelism and reduces the amount of work stealing. Parallel GC pauses is now on par with G1 in presence of large object arrays, reducing pause times by 4-5 times in some cases.

hotspot/gc
 Region Pinning for G1 (JEP 423)

This JEP reduces latency by implementing region pinning in G1, so that garbage collection need not be disabled during Java Native Interface (JNI) critical regions.

Java threads that use native code do not stall garbage collections any more. Garbage collections will execute regardless of native code keeping references to Java objects. The garbage collection will keep objects that may be accessed by native code in place, collecting garbage only in surrounding heap areas but will be otherwise unaffected.

hotspot/gc
 Parallel: Better GC Throughput with Large Object Arrays (JDK-8321013)

During a young collection, Parallel GC searches for dirty cards in the card table to locate old-to-young pointers. After finding dirty cards, Parallel GC uses the internal bookkeeping data structures to locate object starts for heap-parsing to be able to walk the heap within these dirty cards object-by-object.

This change modifies the internal bookkeeping data structure to the one used by Serial and G1. As a result, the object start lookup time is improved and one can observe about a 20% reduction of Young-GC pause in some benchmarks using large object arrays.

hotspot/gc
 Serial: Better GC Throughput with Scarce Dirty Cards (JDK-8319373)

During a young collection, Serial GC searches for dirty cards in the card table to locate old-to-young pointers. After finding dirty cards, Serial GC uses the block offset table to locate object starts for heap-parsing to be able to walk the heap within these dirty cards object-by-object.

This change improves the object start lookup and search for dirty cards resulting in a large (~40%) reduction in Young-GC pause in some benchmarks using large object arrays.

hotspot/gc
 G1: Balance Code Root Scan Phase during Garbage Collection (JDK-8315503)

The Code Root Scan Phase during garbage collection finds references to Java objects in compiled code. To speed up this process, G1 maintains a remembered set for compiled code that contains references into the Java heap. That is, every region contains a set of compiled code that contains references into it.

Assuming that such references are few, previous code used a single thread per region to iterate over a particular region's references, which poses a scalability bottleneck if the distribution of these references is very unbalanced.

G1 now distributes this code root scan work across multiple threads within regions, removing this bottleneck.

security-libs/java.security
 New Security Category for -XshowSettings Launcher Option (JDK-8281658)

The -XshowSettings launcher has a new security category. Settings from security properties, security providers and TLS related settings are displayed with this option. A security sub-category can be passed as an argument to the security category option. See the output from java -X:

   -XshowSettings:security

       show all security settings and continue
   -XshowSettings:security:*sub-category*
       show settings for the specified security sub-category and continue. Possible *sub-category* arguments for this option include:
       all: show all security settings and continue
       properties: show security properties and continue
       providers: show static security provider settings and continue
       tls: show TLS related security settings and continue

Third party security provider details will be reported if they are included in the application class path or module path and such providers are configured in the java.security file.

security-libs/javax.security
 HSS/LMS: keytool and jarsigner Changes (JDK-8302233)

The jarsigner and keytool tools have been updated to support the Hierarchical Signature System/Leighton-Micali Signature (HSS/LMS) signature algorithm. jarsigner supports signing JAR files with HSS/LMS and verifying JAR files signed with HSS/LMS while keytool supports generating HSS/LMS key pairs.

The JDK includes a security provider that supports HSS/LMS signature verification only. In order to use the key pair generation and signing features of keytool and jarsigner, a third-party provider that supports HSS/LMS key pair and signature generation and a keystore implementation that can store HSS/LMS keys is required.

Even though there’s no specific Java SE API to initialize an HSS/LMS key pair generator, keytool can function with a third-party KeyPairGenerator implementation that supports initialization via an integer keysize or a NamedParameterSpec object. In such cases, users are able to provide the parameters using the existing -keysize or -groupname options of keytool.

As part of this change, the JAR specification was modified to repurpose the existing “.DSA” extension for JAR files signed with HSS/LMS and other forthcoming signature algorithms.

security-libs/javax.xml.crypto
 Update XML Security for Java to 3.0.3 (JDK-8319124)

The XML Signature implementation has been updated to Santuario 3.0.3. Support for four new SHA-3 based RSA-MGF1 SignatureMethod algorithms have been added: SignatureMethod.SHA3_224_RSA_MGF1, SignatureMethod.SHA3_256_RSA_MGF1, SignatureMethod.SHA3_384_RSA_MGF1, and SignatureMethod.SHA3_512_RSA_MGF1.

tools/javadoc(tool)
 The inheritDoc Tag and Method Comments Algorithm Have Been Changed (JDK-8285368)

An optional parameter has been added to the inheritDoc tag so that an author can specify the supertype from which to search for inherited documentation. Additionally, the algorithm to search for inherited documentation has been modified to better align with the method inheriting and overriding rules in Java Language Specification.

For more details, see the following sections of the Documentation Comment Specification for the Standard Doclet:

xml/jaxp
 Add a Built-in Catalog to JDK XML Module (JDK-8306055)

A JDK built-in catalog is introduced to host DTDs defined by the Java Platform. The JDK creates a CatalogResolver based on the built-in catalog when needed to function as the default external resource resolver. When no user-defined resolvers are registered, a JDK XML processor will fall back to the default CatalogResolver and will attempt to resolve an external reference before making a connection to fetch it. The fall-back also takes place if a user-defined resolver exists but allows the process to continue when unable to resolve the resource.

If the default CatalogResolver is unable to locate a resource, it will signal the XML processors to continue processing, or skip the resource, or throw a CatalogException. The action it takes is configured with the jdk.xml.jdkcatalog.resolve property. The new property can be set on factory APIs, as a Java system property, or in the JAXP Configuration File. The new property affects all XML processors uniformly.

For further information, see the JDK built-in Catalog section of the java.xml module summary.

xml/jaxp
 Add a JDK Property for Specifying DTD Support (JDK-8306632)

A new property jdk.xml.dtd.support is introduced that determines how XML processors handle DTDs. The new property can be set on factory APIs, as a Java system property, or in the JAXP Configuration File. The new property affects all XML processors uniformly.

The new property complements the two existing DTD properties: disallow-doctype-decl (fully qualified name: http://apache.org/xml/features/disallow-doctype-decl), which is applicable only to the DOM and SAX processors, and supportDTD (javax.xml.stream.supportDTD), which is applicable only to the StAX processor. When one of these existing properties is set on the respective processor factory, its value will take precedence over any value specified for the jdk.xml.dtd.support property.

For further information, see the Configuration section of the java.xml module summary.

hotspot/jfr
 JFR Event for @Deprecated Methods (JDK-8211238)

A new JFR event, jdk.DeprecatedInvocation, has been added to JDK 22 to help users detect their use of deprecated methods located in the JDK.

To record these events in JFR, a user must specify a recording on the command line, like -XX:StartFlightRecording. Starting a recording during runtime, for example, using jcmd or the JFR Java API, will not have these events reported unless -XX:StartFlightRecording is specified on the command line.

An example event would be rendered like this using the JFR tool:

bin/jfr print <recording.jfr>


jdk.DeprecatedInvocation {
  startTime = 23:31:28.431 (2023-12-04)
  method = jdk.jfr.internal.test.DeprecatedThing.foo()
  invocationTime = 23:31:25.954 (2023-12-04)
  forRemoval = true
  stackTrace = [
    jdk.jfr.event.runtime.TestDeprecatedEvent.testLevelAll() line: 96
    ...
  ]
}

The current design will only report direct method invocations where the caller resides outside the JDK. Intra-JDK invocations will not be reported. Additionally, invoking methods declared deprecated but located outside of the JDK, for example in a third-party library, will not be reported, at least not during this first implementation. This might change in the future.

There exists a small restriction in the reporting of invocations from the Interpreter. In the situation where two caller methods are members of the same class, and they invoke the same deprecated method, for example:

public class InterpreterRestriction {

    public static void main(String[] args) {
        invoke1();
        invoke2();
    }
    private static void invoke1() {
        System.getSecurityManager();
    }
    private static void invoke2() {
        System.getSecurityManager();
    }
}

In this situation, only <InterpreterRestriction.invoke1, System.getSecurityManager> will be reported because the Interpreter implementation will consider System.getSecurityManager() to be resolved and linked after the first call. When invoke2() is called, no slow path will be taken for the resolution of the System.getSecurityManager() method because it is already resolved as part of the cpCache. This restriction does not exist in C1 or C2, only in the Interpreter.

When analyzing the reported events, checking all methods in the reported class is recommended. This slight restriction can be resolved using an iterative process; if one call site is fixed, the other will be reported in the next run.

core-libs/java.nio
 BasicFileAttributes.creationTime Returns Birth Time on Linux (JDK-8316304)

On Linux (kernel version 4.11 or newer, glibc version 2.28 or newer), BasicFileAttributes.creationTime now returns the creation or birth time of the file through the stx_btime element of struct statx. In previous JDK releases, the last modified time was returned. If the birth time is supported by the platform but not by the file system, then the epoch 1970-01-01T00:00:00Z is returned.

 

TOP


Removed Features and Options

This section describes the APIs, features, and options that were removed in Java SE 22 and JDK 22. The APIs described here are those that are provided with the Oracle JDK. It includes a complete implementation of the Java SE 22 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 22 and JDK 22 is the Java SE 22 ( JSR 397) Platform Specification, which documents changes to the specification made between Java SE 21 and Java SE 22. 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 22. See CSRs Approved for JDK 22 for the list of CSRs closed in JDK 22.

core-libs
 sun.misc.Unsafe.shouldBeInitialized and ensureClassInitialized Are Removed (JDK-8316160)

The shouldBeInitialized(Class) and ensureClassInitialized(Class) methods have been removed from sun.misc.Unsafe. These methods have been deprecated for removal since JDK 15. java.lang.invoke.MethodHandles.Lookup.ensureInitialized(Class) was added in Java 15 as a standard API to ensure that an accessible class is initialized.

core-libs/java.lang
 Thread.countStackFrames Has Been Removed (JDK-8309196)

The method java.lang.Thread.countStackFrames() has been removed in this release. This method dates from JDK 1.0 as an API for counting the stack frames of a suspended thread. The method was deprecated in JDK 1.2 (1998), deprecated for removal in Java 9, and re-specified/degraded in Java 14 to throw UnsupportedOperationException unconditionally.

java.lang.StackWalker was added in Java 9 as a modern API for walking the current thread's stack.

core-libs/java.lang:reflect
 The Old Core Reflection Implementation Has Been Removed (JDK-8305104)

The new core reflection implementation has been the default since JDK 18 and the old implementation is now removed. The -Djdk.reflect.useDirectMethodHandle=false introduced by JEP 416 to enable the old core reflection implementation becomes a no-op.

core-svc/tools
 Jdeps -profile and -P Option Have Been Removed (JDK-8310460)

Compact profiles became obsolete in Java SE 9 when modules were introduced. The jdeps -profile and -P options were deprecated for removal in JDK 21 and now removed in JDK 22. Customers can use jdeps to find the set of modules required by their applications instead.

 

TOP


Deprecated Features and Options

Additional sources of information about the APIs, features, and options deprecated in Java SE 22 and JDK 22 include:

  • The Deprecated API page identifies all deprecated APIs including those deprecated in Java SE 22.
  • The Java SE 22 ( JSR 397) specification documents changes to the specification made between Java SE 21 and Java SE 22 that include the identification of deprecated APIs and features not described here.
  • JEP 277: Enhanced Deprecation provides a detailed description of the deprecation policy. You should be aware of the updated policy described in this document.

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 and forRemoval=false. The 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 22. See CSRs Approved for JDK 22 for the list of CSRs closed in JDK 22.

core-libs
 sun.misc.Unsafe park, unpark, getLoadAverage, and xxxFence Methods Are Deprecated for Removal (JDK-8315938)

The park, unpark, getLoadAverage, loadFence, storeFence, and fullFence methods defined by sun.misc.Unsafe have been deprecated for removal.

Code using these methods should move to java.util.concurrent.LockSupport.park/unpark (Java 5), java.lang.management.OperatingSystemMXBean.getSystemLoadAverage (Java 6), and java.lang.invoke.VarHandle.xxxFence (Java 9).

hotspot/runtime
 -Xnoagent Option Is Deprecated for Removal (JDK-8312072)

The -Xnoagent option of the java command has been deprecated for removal. This option has been ignored for many releases and doesn't provide any functionality. It will now generate a deprecation warning when used while launching java.

Any existing code which uses this option should be updated to remove reference to this option.

security-libs/java.security
 Deprecation of the jdk.crypto.ec Module (JDK-8308398)

The jdk.crypto.ec module is being deprecated with the intent to remove it. An empty module exists as a transition for developers to fix applications or jlink commands with hard-coded dependencies before removal. The SunEC JCE Provider, which provides Elliptic Curve Cryptography, is now in the java.base module. There should be no difference in cryptographic functionality with this deprecation.

tools/launcher
 -Xdebug and -debug Options Are Deprecated for Removal (JDK-8227229)

The -Xdebug and -debug options of the java command have been deprecated for removal. These options have been ignored for several releases and don't provide any functionality. Using either of these options while launching java will now log a deprecation warning.

Existing applications which use either of these options should be updated to remove references to these options.

TOP

 


Notable Issues Resolved

The following notes describe previous known issues or limitations that have been corrected in this release.

hotspot/runtime
 Java Terminates Unexpectedly on Apple silicon Systems With macOS 14.4 (JDK-8327860)

Apple’s final release of the 14.4 update to macOS 14 Sonoma causes some Java applications on Apple silicon systems (M1/M2/M3) to terminate unexpectedly. The issue is not present on Intel-based systems and affects all Java versions.

Although most Java applications will not be affected, at this time there is no practical way to determine if they will be. There is currently no workaround.

core-libs/java.lang.invoke
 MethodHandles.Lookup::findStaticVarHandle Does Not Eagerly Initialize the Field's Declaring Class (JDK-8291065)

In the previous releases, MethodHandles.Lookup::findStaticVarHandle eagerly initializes the declaring class of the static field when the VarHandle is created. As specified in the specification, the declaring class should be initialized when the VarHandle is operated on if it has not already been initialized. This issue is fixed in this release. The declaring class is no longer eagerly initialized when MethodHandles.Lookup::findStaticVarHandle is called. Existing code that relies on the previous behavior may observe a change of the order of the classes being initialized.

core-libs/java.lang.invoke
 Reimplement MethodHandleProxies::asInterfaceInstance (JDK-6983726)

In previous releases MethodHandleProxies::asInterfaceInstance returns a Proxy instance. MethodHandleProxies::asInterfaceInstance has been reimplemented to return instances of a hidden class that can be unloaded when all instances returned for the same interface becomes unreachable. Once unloaded, subsequent call to MethodHandleProxies::asInterfaceInstance will spin and define a new hidden class that may incur performance overhead.

core-libs/java.time
 Gregorian Era Names with java.time.format APIs (JDK-8306116)

Names for Gregorian eras returned from java.time.format APIs are now correctly retrieved from the CLDR locale data. Prior to this change, these APIs incorrectly used names from the legacy COMPAT locale data. For example, the Gregorian era names "BCE"/"CE" are now returned for the ROOT locale, instead of "BC"/"AD" that are in the COMPAT locale data. For possible compatibility issues and workarounds, refer to JDK-8320431 for more details.

hotspot/gc
 G1: More Deterministic Heap Resize at Remark (JDK-8314573)

During the Remark pause G1 adjusts the Java heap size to keep a minimum and maximum amount of free regions as set via the -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio options.

Before this change, G1 considered Eden regions as occupied (full) for this calculation. This makes heap sizing very dependent on current Eden occupancy, although after the next garbage collection these regions will be empty. With this change, Eden regions are considered as empty (free) for matters of Java heap sizing. This new policy also aligns Java heap sizing to full GC heap sizing.

The effect is that G1 now expands the Java heap less aggressively and more deterministically, with corresponding memory savings but potentially executing more garbage collections.

tools/javac
 ExecutableElement.getReceiverType and ExecutableType.getReceiverType() Changed to Return Annotated Receiver Types for Methods Loaded from Bytecode (JDK-8319196)

The implementation of ExecutableElement.getReceiverType and ExecutableType.getReceiverType now returns a receiver type for methods loaded from bytecode if the type has associated type annotations. Previously, it returned NOTYPE for all methods loaded from bytecode, which prevented associated type annotations from being retrieved.

tools/javac
 TypeMirror Changed to Provide Annotations for Types Loaded from Bytecode (JDK-8225377)

The implementation of TypeMirror now provides access to annotations for types loaded from bytecode. Previously type annotations were not associated with types loaded from bytecode.

Annotation processors can access type annotations for elements using AnnotationMirror#getAnnotationMirrors, and the annotations will be included in the output of AnnotationMirror#toString.

Any programs that relied on annotations being omitted for elements loaded from the classpath should be updated to handle type annotations.

tools/javac
 The javac Compiler Should Not Accept Private Method References with a Type Variable Receiver (JDK-8318160)

Prior to JDK 22, the javac compiler was accepting private method references with a type variable receiver. This implies that the javac compiler was accepting code like:

import java.util.function.*;

class Test {
    private String asString() {
        return "bar";
    }

    static <T extends Test> Function<T, String> foo() {
        return T::asString;
    }
}

Starting from JDK 22 private method references with type variable receiver will be rejected by the javac compiler.

TOP

 


Known Issues

The following notes describe known issues or limitations in this release.

core-libs/java.nio
 Files.readString May Return Incorrect String When Using UTF-16 or Other Charsets (JDK-8325605)

Strings read with java.nio.files.Files.readString may return incorrect strings when decoding with a charset other than US-ASCII, ISO08859-1, or UTF-8. Reading strings with other multi-byte charsets, such as UTF_16, may produce incorrect results.

As a work-around, disable compact strings by setting -XX:-CompactStrings on the command line.

This issue will be fixed in a future update.

hotspot/compiler
 Potential Performance Regression Due to Limited Range Check Elimination (JDK-8314468 (not public))

When the C1 compiler is the only compiler available to the VM, it applies loop predication to remove array access range checks from loop bodies. Due to a defect, this optimization was disabled, potentially leading to a performance regression.

This only affects the client VM or VM's running with the non-default command line flags -XX:+NeverActAsServerClassMachine or -XX:TieredStopAtLevel=[1,2,3].

hotspot/gc
 JVM May Crash or Malfunction When Using ZGC and Non-Default ObjectAlignmentInBytes (JDK-8325074)

Running the JVM with -XX:+UseZGC and non-default value of -XX:ObjectAlignmentInBytes may lead to JVM crashes or incorrect execution.

hotspot/jfr
 JFR: Increased Startup Time when Using -XX:StartFlightRecording (JDK-8319551)

A noticeable increase in startup time can be observed when using the -XX:StartFlightRecording option with smaller applications. This is due to an ongoing initiative to reduce technical debt in the JFR bytecode instrumentation. The work is anticipated to be finished in a future release, resulting in a startup time that is comparable to JDK 21.

TOP


Other Notes

The following notes describe additional changes and information about this release. In some cases, the following descriptions provide links to additional detailed information about an issue or a change.

client-libs/java.awt
 AWT SystemTray API Is Not Supported on Most Linux Desktops (JDK-8322750)

The java.awt.SystemTray API is used for notifications in a desktop taskbar and may include an icon representing an application. On Linux, the Gnome desktop's own icon support in the taskbar has not worked properly for several years due to a platform bug. This, in turn, has affected the JDK's API, which relies upon that.

Therefore, in accordance with the existing Java SE specification, java.awt.SystemTray.isSupported() will return false where ever the JDK determines the platform bug is likely to be present.

The impact of this is likely to be limited since applications always must check for that support anyway. Additionally, some distros have not supported the SystemTray for several years unless the end-user chooses to install non-bundled desktop extensions.

core-libs/java.io
 JLine As The Default Console Provider (JDK-8308591)

System.console() has changed in this release to return a Console with enhanced editing features that improve the experience of programs that use the Console API. In addition, System.console() now returns a Console object when the standard streams are redirected or connected to a virtual terminal. In prior releases, System.console() returned null for these cases. This change may impact code that uses the return from System.console() to test if the VM is connected to a terminal. If needed, running with -Djdk.console=java.base will restore older behavior where the console is only returned when it is connected to a terminal.

A new method Console.isTerminal() has been added to test if console is connected to a terminal.

core-libs/java.io
 java.io.File Drops the Windows Long Path Prefix from Path Strings (JDK-8287843)

On Windows, java.io.File has changed in this release such that creating a File from a path string with a long path prefix (\\\\?\\ or \\\\?\\UNC) will now strip the prefix. This change fixes several anomalies with file path parsing, helps with interoperability with native code when the file path comes from a native program that includes the long path prefix, and also allows methods such as File::getCanonicalFile to return the canonical file from input that initially contained a long path prefix. The change to java.io.File aligns the behavior with the newer API java.nio.file.Path.

The change may be observable to code that depends on File::toString returning a String that has the long path prefix.

This change has no impact to file access, the JDK will continue to use the long path prefix when accessing files that need the prefix.

core-libs/java.lang:reflect
 Reimplement sun.reflect.ReflectionFactory::newConstructorForSerialization with Method Handles (JDK-8315810)

sun.reflect.ReflectionFactory::newConstructorForSerialization is reimplemented with method handles.

When newConstructorForSerialization(C.class, ctor) is called with a constructor whose declaring class is not a superclass of C, the old implementation returned an ill-formed constructor such that if newInstance is invoked, the behavior is unspecified. The new implementation will throw an UnsupportedOperationException instead, to fail fast.

core-libs/java.net
 Corrected ProxySelector Parameter Validation (JDK-8318150)

The java.net.ProxySelector methods select and connectFailure now throw IllegalArgumentException in all ProxySelector implementations when called with invalid parameters.

Previously, the select method of the ProxySelector returned by ProxySelector.of(InetSocketAddress) was incorrectly throwing a NullPointerException when its uri parameter was null or if the protocol could not be determined. The connectFailed method of the same ProxySelector instance returned without checking its parameters for validity.

core-libs/java.util:i18n
 Support for CLDR Version 44 (JDK-8306116)

The locale data based on the Unicode Consortium's CLDR has been upgraded to version 44. Besides the usual addition of new locale data and translation changes, there are two notable date/time format changes from the upstream CLDR:

  • Mexico and Latin American countries changed their time formats from 24 hours to 12 hours (CLDR-16358)
  • The FULL date format for Australia and the United Kingdom no longer has a comma after weekday (CLDR-16974)

Note that those locale data are subject to change in a future release of the CLDR, so users should not assume stability across releases. For more detailed locale data changes, please refer to the Unicode Consortium's CLDR release notes.

hotspot/compiler
 Exit VM for CompileCommand Parsing Errors (JDK-8282797)

-XX:CompileCommand=... will now exit the VM with a non-zero exit code after a parsing error occurs.

hotspot/compiler
 Unify Syntax of CompileOnly and CompileCommand (JDK-8027711)

-XX:CompileOnly=pattern1,[...],patternN is now an alias for -XX:CompileCommand=compileonly,pattern1 [...] -XX:CompileCommand=compileonly,patternN

hotspot/compiler
 jdk.internal.vm.compiler Renamed to jdk.graal.compiler (JDK-8318027)

In preparation for Project Galahad, the jdk.internal.vm.compiler module was renamed to jdk.graal.compiler. Being a JDK internal module, this should be transparent for most Java users. However, scripts that run jlink to create a run-time image containing the Graal compiler module will need to be updated to use the new module name.

hotspot/runtime
 Allow JIT Compilation for -Xshare:dump (JDK-8305753)

It is now possible to enable JIT compilation when creating a CDS archive with the -Xshare:dump JVM option. By default, when -Xshare:dump is specified, the JIT compiler is disabled, as if the -Xint option were specified. This is necessary for creating CDS archives with deterministic content (see JDK-8241071). However, when creating a CDS archive with a very large class list, and when deterministic content is not required, you can add the -Xmixed option along with -Xshare:dump to enable the JIT compiler, which will speed up the archive creation.

hotspot/runtime
 Hotspot hs_err Files Now Print the Lock Stack (JDK-8316735)

A section containing the thread local lock stack has been added to hs_err report files. It only gets printed when the new lightweight locking mode is enabled (-XX:LockingMode=2).

An example is given here with details about the locked objects omitted:

Lock stack of current Java thread (top to bottom):

LockStack[1]: nsk.share.jdi.EventHandler 
...
LockStack[0]: java.util.Collections$SynchronizedRandomAccessList
...

It lists objects which are lightweight locked, through synchronized methods or statements, by the Java thread which is being analyzed. The object which has been locked most recently is printed first. Objects which are not lightweight locked are not displayed in this section.

hotspot/runtime
 Add -XX:UserThreadWaitAttemptsAtExit=<number_of_waits> (JDK-8314243)

A new flag, -XX:UserThreadWaitAttemptsAtExit=<number_of_waits>, has been introduced. This flag is to specify the number of times the JVM waits for user threads to stop executing native code during a JVM exit. Each wait lasts 10 milliseconds. The maximum number of waits is 1000, to wait at most 10 seconds. By default, UserThreadWaitAttemptsAtExit is 30, thus the JVM may wait up to 300 milliseconds for user threads to stop executing native code when the JVM is exiting. That is the same as the existing behavior.

hotspot/runtime
 The Linux Specific Options UseSHM and UseHugeTLBFS Are Now Obsolete (JDK-8261894)

On Linux, if UseLargePages is enabled and UseTransparentHugePages is disabled, static or explicit large page mode, the options UseSHM and UseHugeTLBFS existed to switch between the two different implementations:

  • UseHugeTLBFS would cause the JVM to use POSIX APIs for allocating large pages.
  • UseSHM would let the JVM would use System V APIs. UseHugeTLBFS had been the default if both options were omitted.

The UseSHM mode offered no advantage over UseHugeTLBFS and has therefore been removed. The switch UseSHM has been obsoleted.

The JVM will now always use POSIX APIs for managing large pages. The switch UseHugeTLBFS has also been obsoleted; UseHugeTLBFS is now unconditionally enabled and cannot be switched off.

hotspot/runtime
 Add User Facing Warning If THPs Are Enabled but Cannot Be Used (JDK-8313782)

On Linux, if the JVM is started with +UseTransparentHugePages but the system does not support Transparent Huge Pages, a warning will now be printed to stdout:

UseTransparentHugePages disabled; transparent huge pages are not supported by the operating system.

hotspot/runtime
 NMT: Make Peak Values Available in Release Builds (JDK-8317772)

NMT reports will now show peak values for all categories. Peak values contain the highest value for committed memory in a given NMT category over the lifetime of the JVM process.

If the committed memory for an NMT category is currently at peak, NMT prints "at peak"; otherwise, it prints the peak value.

For example:

-                  Compiler (reserved=230KB, committed=230KB)

                            (malloc=34KB #64) (peak=49KB #71) 
                            (arena=196KB #4) (peak=6126KB #16)

This shows Compiler arena memory peaked at a bit more than 6MB, whereas it now hovers around 200 KB.

hotspot/svc
 Two Phase Segmented Heap Dump (JDK-8306441)

During a heap dump, the application must pause execution and wait for the VM to complete the heap dump before resuming. This enhancement aims to minimize application pause time as much as possible by dividing the heap dump into two phases:

  • Phase one: Concurrent threads directly write data to segmented heap files (application is paused).
  • Phase two: Multiple heap files are merged into a complete heap dump file (application is resumed).

This approach significantly reduces application pause time, but it is important to note that the total time required for the heap dump itself remains unchanged. This optimization solely focuses on minimizing the impact on the application's pause time.

When executing jmap or jcmd GC.heap_dump, the VM automatically selects an appropriate number of parallel threads based on the type of garbage collector, number of processors, heap size, and degree of fragmentation. It will attempt to perform a parallel heap dump whenever possible, falling back to using a single thread when a parallel heap dump is not possible. In this case, the heap dump behavior is the same as before, and the details of the heap dump can be observed using the -Xlog:heapdump option.

security-libs/java.security
 Added Certigna Root CA Certificate (JDK-8314960)

The following root certificate has been added to the cacerts truststore:

+ Certigna (Dhimyotis)

  + certignarootca
    DN: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR

security-libs/java.security
 Added Four Root Certificates from DigiCert, Inc. (JDK-8318759)

The following root certificates have been added to the cacerts truststore:

+ DigiCert, Inc.

  + digicertcseccrootg5
    DN: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US

+ DigiCert, Inc.
  + digicertcsrsarootg5
    DN: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US

+ DigiCert, Inc.
  + digicerttlseccrootg5
    DN: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US

+ DigiCert, Inc.
  + digicerttlsrsarootg5
    DN: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US

security-libs/java.security
 Added Three Root Certificates from eMudhra Technologies Limited (JDK-8319187)

The following root certificates have been added to the cacerts truststore:

+ eMudhra Technologies Limited

  + emsignrootcag1
    DN: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN

+ eMudhra Technologies Limited
  + emsigneccrootcag3
    DN: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN

+ eMudhra Technologies Limited
  + emsignrootcag2
    DN: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN

security-libs/java.security
 Added Telia Root CA v2 Certificate (JDK-8317373)

The following root certificate has been added to the cacerts truststore:

+ Telia Root CA v2

  + teliarootcav2
    DN: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI

security-libs/java.security
 Increase Default Value of the System Property jdk.jar.maxSignatureFileSize (JDK-8312489)

The system property, jdk.jar.maxSignatureFileSize, allows applications to control the maximum size of signature files in a signed JAR. Its default value has been increased from 8000000 bytes (8 MB) to 16000000 bytes (16 MB).

security-libs/java.security
 Added ISRG Root X2 CA Certificate from Let's Encrypt (JDK-8317374)

The following root certificate has been added to the cacerts truststore:

+ Let's Encrypt

  + letsencryptisrgx2
    DN: CN=ISRG Root X2, O=Internet Security Research Group, C=US

security-libs/javax.crypto
 KEM.getInstance() Should Check If a Third-Party Security Provider Is Signed (JDK-8322971)

When instantiating a third-party security provider's implementation (class) of a KEM algorithm, the framework will determine the provider's codebase (JAR file) and verify its signature. In this way, JCA authenticates the provider and ensures that only providers signed by a trusted entity can be plugged into the JCA. This is consistent with other JCE service classes, such as Cipher, Mac, KeyAgreement, and others.

security-libs/javax.net.ssl
 Add Separate System Properties for TLS Server and Client for Maximum Chain Length (JDK-8311596)

Two new system properties, jdk.tls.server.maxInboundCertificateChainLength and jdk.tls.client.maxInboundCertificateChainLength, have been added to set the maximum allowed length of the certificate chain accepted from the client or server during TLS/DTLS handshaking.

A service can function as both a TLS/DTLS server and client. When the service acts as a server, it enforces a maximum certificate chain length accepted from clients. When the service acts as a client, it enforces a maximum certificate chain length accepted from servers.

These properties, if set, override the existing jdk.tls.maxCertificateChainLength system property. The properties work together as follows:

If the jdk.tls.server.maxInboundCertificateChainLength system property is set and its value is greater than or equal to 0, this value will be used to enforce the maximum length of a client certificate chain accepted by a server. Otherwise, if the jdk.tls.maxCertificateChainLength system property is set and its value is greater than or equal to 0, this value will be used to enforce it. If neither property is set, a default value of 8 will be used for enforcement.

If the jdk.tls.client.maxInboundCertificateChainLength system property is set and its value is greater than or equal to 0, this value will be used to enforce the maximum length of a server certificate chain accepted by a client. Otherwise, if the jdk.tls.maxCertificateChainLength system property is set and its value is greater than or equal to 0, this value will be used to enforce it. If neither property is set, a default value of 10 will be used for enforcement.

In this release, the default maximum chain length accepted from clients has been changed from 10 to 8 for client certificate chains.

security-libs/org.ietf.jgss:krb5
 Read Files in includedir in Alphanumeric Order (JDK-8309356)

JDK 10 added support for the includedir DIRNAME directive in krb5.conf. With this code change, files in this directory are read in alphanumeric order. Prior to this change, the files were read in no specific order. This is to be consistent with MIT krb5 1.17 (released on 2019-01-08).

tools/javac
 Align javac with the Java Language Specification by Rejecting final in Record Patterns (JDK-8317300)

JDK 21 introduced pattern matching in the Java language. However, javac allowed final in front of a record pattern, such as (case final R(...) ->), something which is not allowed by the Java Language Specification.

Programs that could be compiled erroneously in JDK21 with final will now fail to compile. This change fixes the issue in the compiler. Impacted users will need to remove the final keyword.

tools/javac
 Add lint Warning for Restricted Method Calls (JDK-8316971)

Some methods in the Foreign Function & Memory API are unsafe. When used improperly, these methods can lead to loss of memory safety which can result in a JVM crash or silent memory corruption. Accordingly, the unsafe methods in the FFM API are restricted. This means that their use is permitted, but by default causes a warning to be issued at run time. To indicate where run time warnings may occur, a new javac lint option, -Xlint:restricted, causes warnings to be issued at compile time if restricted methods are called in source code. These compile-time warnings can be suppressed using @SuppressWarnings("restricted").

tools/javac
 When Using --release N, the System Module Descriptors Will Contain N As the Module Version (JDK-8318913)

For release builds of the JDK, when javac is used with --release N, the module descriptors for system modules will always contain N as their module version, regardless of the current JDK release and update release versions.

For pre-release builds of JDK, the version will contain the pre-release identifiers in addition to N.

Previously, the module version encoded in the module descriptors was either missing, for JDK release N, and --release M, where M < N, or the full module version, including update versions for JDK release N and --release N.

tools/launcher
 Available Locales Information Now Listed with -XshowSettings:locale Option (JDK-8310201)

The showSettings launcher option no longer prints available locales information by default, when -XshowSettings is used. The -XshowSettings:locale option will continue to print all settings related to available locales.

tools/launcher
 -XshowSettings Launcher Behavior Changes (JDK-8311653)

The -XshowSettings:all and -XshowSettings launch options now differ in behavior. -XshowSettings will print a summary view for the locale and security categories and all information for the other categories. -XshowSettings:all will continue to print all settings information available.

The -XshowSettings launcher option will now reject bad values passed to it. In such cases, an error message is printed and the JVM launch is aborted. See java -X for valid options that can be used with the -XshowSettings option.

 

TOP


Differences Between Oracle JDK and OpenJDK

Although we have stated the goal to have Oracle JDK and OpenJDK binaries be as close to each other as possible, there remain several differences between the two options.

The current differences are:

  • Oracle JDK offers "installers" (msi, rpm, deb, etc.) which not only place the JDK binaries in your system but also contain update rules and in some cases handle some common configurations like set common environmental variables (such as, JAVA_HOME in Windows) and establish file associations (such as, use java to launch .jar files). OpenJDK is offered only as compressed archive (tar.gz or .zip).
  • Usage Logging is only available in Oracle JDK.
  • Oracle JDK requires that third-party cryptographic providers be signed with a Java Cryptography Extension (JCE) Code Signing Certificate. OpenJDK continues allowing the use of unsigned third-party crypto providers.
  • The output of java -version is different. Oracle JDK returns java and includes the Oracle-specific identifier. OpenJDK returns OpenJDK and does not include the Oracle-specific identifier.
  • Oracle JDK 17 and later are released under the Oracle No-Fee Terms and Conditions License.OpenJDK is released under GPLv2wCP. License files included with each will therefore be different.
  • Oracle JDK distributes FreeType under the FreeType license and OpenJDK does so under GPLv2. The contents of \legal\java.desktop\freetype.md is therefore different.
  • Oracle JDK has Java cup and steam icons and OpenJDK has Duke icons.
  • Oracle JDK source code includes "ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms." Source code distributed with OpenJDK refers to the GPL license terms instead.