JDK 17: The new features in Java 17

The latest long-term support release of standard Java features always-strict floating point semantics, a foreign function and memory API, a uniform API for pseudo random number generators, and much more.

JDK 17: The new features in Java 17
Jessica Lewis (CC0)

Java 17, a new long-term support (LTS) release of standard Java, is now available for production use. Oracle also announced that LTS releases, which receive at least eight years of product support, henceforth will arrive every two years, as opposed to the three years between releases in the past. Non-LTS releases get six months of support from Oracle.

Among the new capabilities in the new version of standard Java are context-specific deserialization filters support, which is a security enhancement, and a preview of pattern matching for switch statements. JDK 17 features everything that has been added since the last LTS release, JDK 11, which arrived three years ago.

More frequent LTS releases will provide faster access to new features for companies that just want to use the LTS releases, Georges Saab, vice president of Oracle’s Java platform group, said. The next LTS release will be Java 21 in 2023. With JDK 17, Oracle will allow free use of Oracle JDK binaries in production for three years, one year past the next LTS. But that does not include an enterprise production support subscription.

Data from the customer base of application monitoring provider New Relic, representing tens of millions of production JVMs, show that LTS releases have almost unanimous deployment. New Relic found that nearly 100 percent of users are running either JDK 11 or JDK 8, the two most recent LTS releases. New Relic said 90 percent were running JDK 11 and 10 percent JDK 8.

However, Oracle said downloads of the six-month releases have been steadily increasing. Developers like to try out the six-month releases while enterprises want to deploy the LTS releases.

Production builds of JDK 17 can be found at oracle.com. OpenJDK open source builds also are available. New features of JDK 17 include the following: 

  • Context-specific deserialization filters allow applications to configure context-specific and dynamically selected deserialization filters via a JVM-wide filter factory invoked to select a filter for each serialization operation. In explaining the motivation behind this proposal, Oracle said deserializing untrusted data is an inherently dangerous activity because the content of the incoming data streams determines the objects that are created, the values of their fields, and references between them. In many uses, the bytes in the stream are received from an unknown, untrusted, or unauthenticated client. With careful construction of the stream, an adversary can cause code in arbitrary classes to be executed with malicious intent. If object construction has side effects that change state or invoke other actions, those actions could compromise the integrity of application objects, library objects, and the Java runtime. The key to disabling serialization attacks is to prevent instances of arbitrary classes from being deserialized, thereby preventing the direct or indirect execution of their methods. Deserialization filters were introduced in Java 9 to enable application and library code to validate incoming data streams before deserializing them. This code supplies validation logic as a java.io.ObjectInputFilter when it creates a deserialization stream. However, relying on a stream’s creator to explicitly request validation has limitations. JDK Enhancement Proposal 290 addressed these limitations by introducing a JVM-wide deserialization filter that can be set via an API, system properties, or security properties, but this approach also has limits, particularly in complex applications. A better approach is to configure per-stream filters such that they do not require the participation of every stream creator. The planned enhancement should help developers construct and apply appropriate filters for each deserialization context and use case.
  • With the restoration of always-strict floating point semantics, floating-point operations will be made consistently strict, rather than having both strict floating point semantics (strictfp) and subtly different default floating point semantics. This restores the original floating point semantics to the language and VM, matching the semantics before the introduction of strict and default floating point modes in Java Standard Edition 1.2. Goals of this effort include easing development of numerically sensitive libraries including java.lang.Math and java.lang.StrictMath. The impetus for changing the default floating point semantics in the late-1990s stemmed from bad interaction between the original Java language and JVM semantics and some peculiarities of the x87 floating point coprocessor instruction set of the popular x86 architecture. Matching the exact floating point semantics in all cases, including subnormal operands and results, required large overheads of additional instructions. Matching the results in the absence of overflow or underflow could be done with less overhead and that is roughly what is allowed by the revised default floating point semantics introduced in Java SE 1.2. But the SSE2 (Streaming SIMD Extensions 2) extensions, shipped in Pentium 4 and later processors starting circa 2001, could support strict JVM floating point operations in a straightforward manner without undue overhead. Since Intel and AMD support SSE2 and later extensions that allow natural support of strict floating point semantics, the technical motivation for having a default floating point semantics different than strict no longer exists.
  • Deprecation of the Security Manager, preparing for removal in a future release. Dating back to Java 1.0, Security Manager has been the primary means of securing client-side Java code and has rarely been used to secure server-side code. A goal of the proposal is evaluating whether new APIs or mechanisms are needed to address specific narrow use cases for which Security Manager has been used, such as blocking System::exit. Plans call for deprecating the Security Manager for removal in concert with the legacy Applet API, which also is slated to be deprecated in JDK 17.
  • A preview of pattern matching for switch extends the language of patterns in Java to allow switch expressions and statements to be tested against a number of patterns, each with a specific action. This enables complex data-oriented queries to be expressed concisely and safely. Among the goals of this feature include expanding the expressiveness and application of switch expressions and statements by enabling patterns to appear in case labels, relaxing the historical null-hostility of switch when desired, and introducing two kinds of patterns: guarded patterns, which allow pattern matching logic to be refined with arbitrary Boolean expressions, and parenthesized patterns, which resolve some parsing ambiguities. In JDK 16, the instanceof operator was extended to take a type pattern and perform pattern matching. The modest extension proposed allows the familiar instanceof-and-cast idiom to be simplified.
  • Strong encapsulation for JDK internals, except for critical internal APIs such as sun.misc.Unsafe, would make it no longer be possible to relax the strong encapsulation of internal elements via a single command-line option, as was doable in JDK 9 through JDK 16. Goals of the plan include improving security and maintainability of the JDK and encouraging developers to migrate from internal elements to standard APIs.
  • Removal of the Remote Method Invocation (RMI) Activation mechanism while preserving the rest of RMI. The RMI Activation mechanism is obsolete and disused and was deprecated for removal in JDK 15.
  • The foreign function and memory API, introduced in an incubator stage, allows Java programs to interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions, i.e., code outside the JVM, and 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 risk of JNI (Java Native Interface). The API proposed is the evolution of two APIs — the foreign memory access API and the foreign linker API. The foreign memory access API was targeted to Java 14 in 2019 as an incubating API and re-incubated in Java 15 and Java 16. The foreign linker API was targeted to Java 16 as an incubating API in late-2020. Goals of the API plan include ease of use, performance, generality, and safety.
  • Integrated into JDK 16 as an incubating API, the platform-agnostic vector API will be incubated again in JDK 17, providing a mechanism to express vector computations that reliably compile at run time to optimal vector instructions on supported CPU architectures. This achieves better performance than equivalent scalar computations. In JDK 17, the vector API has been enhanced for performance and implementation, including enhancements to translate byte vectors to and from boolean arrays.
  • Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them. Goals of the proposal include allowing the author of a class or interface to control which code is responsible for implementing it, providing a more declarative way than access modifiers to restrict the use of a superclass, and supporting future directions in pattern matching by providing a foundation for the exhaustive analysis of patterns. This capability helps API designers build more resilient code.
  • Removal of the experimental AOT and JIT compiler, which has seen little use but requires significant maintenance effort. The plan calls for maintaining the Java-level JVM compiler interface so developers can keep using externally built versions of the compiler for JIT compilation. AOT compilation (the jaotc tool) was incorporated into JDK 9 as an experimental feature. The tool uses the Graal compiler, which is itself written in Java, for AOT compilation. These experimental features were not included in JDK 16 builds published by Oracle and no one complained. Under the plan prescribed, three JDK modules would be removed: jdk.aot (the jaotc tool); internal.vm.compiler, the Graal compiler; and jdk.internal.vm.compiler.management, the Graal MBean. HotSpot code related to AOT compilation also would be removed.
  • Porting the JDK to MacOS/AArch64 in response to Apple’s plan to transition its Macintosh computers from x64 to AArch64. An AArch64 port for Java already exists for Linux and work is underway for Windows. Java builders expect to reuse existing AArch64 code from these ports by employing conditional compilation, as is the norm in ports of the JDK, to accommodate differences in low-level conventions such as the application binary interface and the set of reserved processor registers. Changes for MacOS/AArch64 risk breaking the existing Linux/AArch64, Windows/AArch64, and MacOS/x64 ports, but the risk will be reduced through pre-integration testing.
  • Deprecating the Applet API for removal. This API is essentially irrelevant, since all web browser vendors either have removed support for Java browser plug-ins or have announced plans to do so. The Applet API previously was deprecated, but not for removal, in Java 9 in September 2017.
  • A new rendering pipeline for MacOS, using the Apple Metal API as an alternative to the existing pipeline that uses the deprecated OpenGL API. This proposal is intended to provide a fully functional rendering pipeline for the Java 2D API that uses the MacOS Metal framework and be ready in the event Apple removes the OpenGL API from a future version of MacOS. The pipeline is intended to have functional parity with the existing OpenGL pipeline, with performance as good or better in select applications and benchmarks. A clean architecture would be created that fits into the current Java 2D model. The pipeline would coexist with the OpenGL pipeline until obsolete. It is not a goal of the proposal to add any new Java or JDK APIs.
  • Enhanced pseudo-random number generators that would provide new interface types and implementations for pseudorandom number generators (PRNGs) including jumpable PRNGs and an additional class of splittable PRNG algorithms (LXM). A new interface, RandomGenerator, would supply a uniform API for all existing and new PRNGs. Four specialized RandomGenerator interfaces would be provided. Motivating the plan is a focus on multiple areas for improvement in the area of pseudorandom number generation in Java. The effort does not call for providing implementations of numerous other PRNG algorithms. But three common algorithms have been added that already are widely deployed in other programming language environments. Goals of the plan include:
    • Making it easier to use various PRNG algorithms interchangeably in applications.
    • Improved support for stream-based programming, providing streams of PRNG objects.
    • Elimination of code duplication in existing PRNG classes.
    • Preservation of existing behavior of class java.util.Random.

Copyright © 2021 IDG Communications, Inc.