JDK 21: The new features in Java 21

Plans for Java 21, due in September, now include a key encapsulation mechanism API and deprecation of the 32-bit Windows port.

Java 21 is brewing
jazz3311 / Shutterstock

Java Development Kit (JDK) 21, due in September as the next long-term support release of Oracle’s standard Java implementation, now has 13 features officially proposed for it, with two more features added in recent days.

The latest proposals include a key encapsulation mechanism (KEM) API and deprecation of the 32-bit x86 Windows port. Three other features—a generational Shenandoah garbage collector, unnamed classes and instance main methods, and unnamed patterns and variables—were added earlier this month.

These five proposals join eight features proposed in March and April: a generational ZGC (Z Garbage Collector), record patterns, pattern matching for switch expressions and statements, a vector API, sequenced collections, virtual threads, a preview of string templates, and a third preview of a foreign function and memory API. Separately, JDK 21 also is due to change how network names are assigned to network interfaces on Windows.

Early-access binaries under the GPL are available at jdk.java.net. Oracle publishes new releases of standard Java every six months, with the most recent, JDK 20, having arrived March 21. The specific proposals for JDK 21 so far include:

  • Key encapsulation mechanism API, an encryption technique for securing symmetric keys via public cryptography. One goal of the proposal is to enable applications to use KEM algorithms such as the RSA Key Encapsulation Mechanism (RSA-KEM), the Elliptic Curve Integrated Encryption Scheme (ECIES), and candidate algorithms for the National Institute of Standards and Technology (NIST) Post-Quantum Cryptography standardization process. Another goal is to enable use of KEMs in higher level protocols such as Transport Layer Security (TLS) and in cryptographic schemes such as Hybrid Public Key Encryption (HPKE). Also, security providers would be able to implement KEM algorithms in either Java code or native code, and include an implementation of the Diffie-Hellman KEM (DHKEM) defined in RFC 9180.
  • Deprecation of the Windows 32-bit x86 port for removal, with the goal to remove it in a future release. The proposal is intended to update the build system to issue an error message when an attempt is made to configure a build for Windows 32-bit x86. The message will be suppressible via a new configuration option. Also, the plan is to mark the port, and related port-specific features, as deprecated for removal in relevant documentation. The proposal notes that Windows 10, the last Windows OS to support 32-bit operation, reaches end of life in October 2025.
  • Generational Shenandoah, a proposal to enhance the Shenandoah GC with experimental generation collection capabilities to boost sustainable throughput, load-spike resilience, and memory utilization. The main goal of the proposal is to provide an experimental generational mode without breaking non-generational Shenandoah, with the intent to make the generational mode the default in a future release. Other goals include reducing the sustained memory footprint without sacrificing low GC pauses, reducing CPU and power usage, sustaining high throughput, and continuing to support compressed object pointers. The proposal initially would support x64 and AArch64, with support for other instruction sets added as the experimental mode progresses to readiness. It is not a goal to replace non-generational Shenandoah, which will continue as the default mode of operation with no regressions in its performance or functionality. Improving performance of every conceivable workload also is not a goal.
  • A preview of unnamed classes and instance main methods, to evolve the language so that students will be able write their first Java programs without needing to understand language features designed for large programs. Far from using a separate dialect of Java, students could write streamlined declarations for single-class programs and then seamlessly expand programs to use more advanced features as their skills grow. The intent is to offer a smooth onramp to Java.
  • A preview of unnamed patterns and variables, to enhance the language with unnamed patterns and unnamed variables. Unnamed patterns match a record component without stating the component’s name or type, while unnamed variables can be initialized but not used. Both are denoted by an underscore character, _. This proposal is intended to improve the readability of record patterns by eliding unnecessary nested patterns, and to improve maintainability of all code by identifying variables that must be declared but will not be used.
  • Generational ZGC is intended to improve application performance by extending ZGC to maintain separate generations for young and old objects. Young objects tend to die young, and maintaining separate generations will allow ZGC to collect them more frequently. Applications running with generational ZGC should see the following benefits: lower risks of allocation stalls, lower required heap memory overhead, and lower garbage collection CPU overhead. These benefits should happen without significant throughput reduction compared to non-generational ZGC.
  • Record patterns, previewed in both JDK 19 and JDK 20, would deconstruct record values. Record patterns and type patterns can be nested to enable a powerful, declarative, and composable form of data navigation and processing. Goals of the proposal include extending pattern matching to destructure instances of record classes and adding nested patterns, enabling more composable data queries. This feature has co-evolved with pattern matching for switch. Record patterns in the current JEP (JDK Enhancement Proposal) proposes to finalize the feature with further refinements based on continued experience and feedback. Apart from minor editorial changes, the main change since the second preview is to remove support for record patterns appearing in the header of an enhanced for statement. The feature may be re-proposed in a future JEP.
  • Pattern matching for switch enables a switch expression or statement to be tested against a number of patterns, each with a specific action, so complex data-oriented queries can be expressed safely and concisely. This feature originally was proposed in JDK 17 and subsequently was refined in JDK 18, JDK 19, and JDK 20. It would be finalized in JDK 21 with further refinements based upon feedback and experience. Main changes from previous JEPs are the removal of parenthesized patterns and allowing qualified enum constants such as case constants with switch expressions and statements. Goals include expanding the expressiveness and applicability of switch expressions and statements by allowing patterns to appear in case labels, allowing historical null-hostility of switch to be relaxed when desired, and increasing the safety of switch statements by requiring that pattern switch statements cover all potential input values. Another goal is ensuring existing switch expressions and statements continue to compile with no changes and execute with identical semantics.
  • A sixth incubator of a vector API to express vector computations that reliably compile at run time to optimal vector instructions on supported CPU architectures, achieving performance superior to equivalent scalar computations. This previously has been incubated in JDK 16 through JDK 20. The latest incarnation includes performance enhancements and bug fixes. Goals of the proposal include being clear and concise, being platform agnostic, and offering reliable runtime compilation and performance on x64 and AArch64 architectures. Other goals include graceful degradation, for when a vector computation cannot be fully expressed at runtime as a sequence of vector instructions, and alignment with Project Valhalla.
  • The foreign function and memory API enables Java programs to interoperate with code and data outside the Java runtime. By efficiently invoking foreign functions and safely accessing foreign memory, this preview API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI (Java Native Interface). The API previously was previewed in JDK 20, which debuted last month, and JDK 19, which was released in September 2022. Refinements in the latest preview include enhanced layout paths with a new element to dereference address layouts, centralized management of the lifetimes of native segments in the Arena interface, a fallback native linker implementation, and removal of the VaList. Goals of the proposal include ease of use, performance, generality, and safety. It is not a goal to either reimplement JNI on top of this API or change JNI in any way.
  • Virtual threads are lightweight threads that promise to “dramatically” reduce the effort of writing, maintaining, and observing high-throughput concurrent applications. Goals of the plan include enabling server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization, enabling existing code that uses the lang.Thread API to adopt virtual threads with minimal change, and enabling easy debugging and profiling of virtual threads with current JDK tools. Previously previewed in both JDK 20 and JDK 19, virtual threads will be finalized in JDK 21. With JDK 21, virtual threads now support thread-local variables all of the time, and make it impossible to create virtual threads that do not have these variables. Guaranteed support for thread-local variables ensures that more existing libraries can be used unchanged with virtual threads and assists with migrating task-oriented code to use virtual threads.
  • Sequenced collections introduces interfaces to represent collections with a defined encounter order. Each collection has well-defined first and second elements and so forth, to the last element. Uniform APIs are provided for accepting first and last elements and processing elements in reverse order. Motivating the proposal is a situation in which Java’s collections framework lacks a collection type to represent a sequence of elements with a defined encounter order. It also lacks a uniform set of operations that apply across these collections. These gaps have been a problem and a source of complaints. The proposal calls for defining interfaces for sequencing for collections, sets, and maps, and retrofitting this into the existing collections type hierarchy. All of these new methods have default implementations.
  • String templates, to appear as a preview feature, complement Java’s existing string literals and text blocks by coupling literal text with embedded expressions and processors to produce specialized results. This language feature and API is intended to simplify writing of Java programs by making it easy to express strings that include values computed at runtime. It promises to enhance readability of expressions, improve program security, retain flexibility, and simplify the use of APIs that accept strings written in non-Java languages. Enabling development of non-string expressions derived from combining literal text and embedded expressions also is a goal.

Separate from these JEPs, network names that the JDK assigns to network interfaces on Windows are slated to change in JDK 21, according to the Java team at Oracle. Maintainers of applications that do network multicasting or that use the java.net.NetworkInterface API are advised to note the change.

The JDK historically synthesized names for network interfaces on Windows. This has been changed to use names assigned by the Windows OS. The change may impact code that does a lookup of network interfaces using the NetworkInterface.GgetbyName(String-name) method. 

The proposed release schedule for JDK 21 includes rampdown phases occurring June 8 and July 20. The feature set is frozen at the first rampdown phases while bug fixes continue. This is followed by initial and final release candidates on August 10 and August 24, with bug fixes still possible, followed by general availability on September 19.

As a long-term support (LTS) release, JDK 21 would get five years of Premier support and extended support until September 2031. The current LTS release is JDK 17, published in September 2021. Non-LTS releases, such as JDK 20 and JDK 19, receive only six months of premier support and no extended support.

A number of other potential features could be added to JDK 21. One is a preview of scoped values for sharing immutable data within and across threads. This feature was incubated in JDK 20. A second possibility is graduating structured concurrency, a proposal to streamline error handling and improve reliability, to preview status. This feature was previously incubated in JDK 19 and JDK 20.

A feature to prepare to disallow the dynamic loading of agents is a third possibility. This feature would issue warnings when agents are loaded dynamically into a running JVM, in preparation for a future release that would disallow loading of dynamic agents by default. Finally, a fourth potential feature for JDK 21 is an experimental compact object headers capability, designed to reduce the size of object headers in the JVM to reduce heap size.

Copyright © 2023 IDG Communications, Inc.

InfoWorld Technology of the Year Awards 2023. Now open for entries!