It has happened: after many years of deprecation warnings and back-and-forth conversations, the SecurityManager is effectively dead. JDK-24, released just last week, sets a final point in this long story. But there is no time to grieve, so many new features in JDK-24 to talk about!
The JDK-24 is really packed with JEPs, nonetheless some of them are being dragged from the previous JDK releases. Let us kick off from the finalized features first, with the preview / experimental / incubating to follow right after.
JEP-472: Prepare to Restrict the Use of JNI: issues warnings about uses of the Java Native Interface (JNI) and adjusts the Foreign Function & Memory (FFM) API to issue warnings in a consistent manner. All such warnings aim to prepare developers for a future release that ensures integrity by default by uniformly restricting JNI and the FFM API. Application developers can avoid both current warnings and future restrictions by selectively enabling these interfaces where essential.
Code that uses JNI is affected by native access restrictions if
- It calls System::loadLibrary, System::load, Runtime::loadLibrary, or Runtime::load, or
- It declares a native method.
The following warnings are going to be issued:
WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::loadLibrary has been called by com.example.LoadLibraryRunner in an unnamed module (...) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled
As per the hints above, to enable native access selectively, you could use the following command-line options:
$ java --enable-native-access=ALL-UNNAMED ...
(all code on the class path)$ java --enable-native-access=M1,M2, ...
(specific modules on the module path)
Alternatively, you could add
Enable-Native-Access: ALL-UNNAMED
to the manifest of an executable JAR file (MANIFEST.MF
). The only supported value for theEnable-Native-Access
manifest entry isALL-UNNAMED
; other values cause an exception to be thrown. For more details, please check Quality Outreach Heads-up - JDK 24: Prepares Restricted Native Access write-up.JEP-498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe: issues a warning at run time on the first occasion that any memory-access method in
sun.misc.Unsafe
is invoked. All of these unsupported methods were terminally deprecated in JDK 23. They have been superseded by standard APIs, namely the VarHandle API (JEP 193, JDK 9) and the Foreign Function & Memory API (JEP 454, JDK 22).In case when usage of the
sun.misc.Unsafe
memory-access methods is detected, the following warnings are going to be issued:WARNING: A terminally deprecated method in sun.misc.Unsafe has been called WARNING: sun.misc.Unsafe::allocateMemory has been called by com.example.UnsafeRunner (...) WARNING: Please consider reporting this to the maintainers of class com.example.UnsafeRunner WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
JEP-491: Synchronize Virtual Threads without Pinning: improves the scalability of Java code that uses synchronized methods and statements by arranging for virtual threads that block in such constructs to release their underlying platform threads for use by other virtual threads. This will eliminate nearly all cases of virtual threads being pinned to platform threads, which severely restricts the number of virtual threads available to handle an application's workload.
JEP-475: Late Barrier Expansion for G1: simplifies the implementation of the G1 garbage collector's barriers, which record information about application memory accesses, by shifting their expansion from early in the C2 JIT's compilation pipeline to later.
JEP-479: Remove the Windows 32-bit x86 Port: removes the source code and build support for the Windows 32-bit x86 port. This port was deprecated for removal in JDK 21 with the express intent to remove it in a future release.
JEP-490: ZGC: Remove the Non-Generational Mode: removes the non-generational mode of the Z Garbage Collector (ZGC), keeping the generational mode as the default for ZGC.
JEP-501: Deprecate the 32-bit x86 Port for Removal: deprecates the 32-bit x86 port, with the intent to remove it in a future release. This will thereby deprecate the Linux 32-bit x86 port, which is the only 32-bit x86 port remaining in the JDK. It will also, effectively, deprecate any remaining downstream 32-bit x86 ports. After the 32-bit x86 port is removed, the architecture-agnostic Zero port will be the only way to run Java programs on 32-bit x86 processors.
JEP-493: Linking Run-Time Images without JMODs: reduces the size of the JDK by approximately 25% by enabling the jlink tool to create custom run-time images without using the JDK's JMOD files. This feature must be enabled when the JDK is built; it will not be enabled by default, and some JDK vendors may choose not to enable it.
JEP-496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism: enhances the security of Java applications by providing an implementation of the quantum-resistant Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM). Key encapsulation mechanisms (KEMs) are used to secure symmetric keys over insecure communication channels using public key cryptography. ML-KEM is designed to be secure against future quantum computing attacks. It has been standardized by the United States National Institute of Standards and Technology (NIST) in FIPS 203.
JEP-497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm: enhances the security of Java applications by providing an implementation of the quantum-resistant Module-Lattice-Based Digital Signature Algorithm (ML-DSA). Digital signatures are used to detect unauthorized modifications to data and to authenticate the identity of signatories. ML-DSA is designed to be secure against future quantum computing attacks. It has been standardized by the United States National Institute of Standards and Technology (NIST) in FIPS 204.
JEP-484: Class-File API: provides a standard API for parsing, generating, and transforming Java class files. This JEP finalizes the Class-File API that was originally proposed as a preview feature by JEP 457 in JDK 22 and refined by JEP 466 in JDK 23.
JEP-486: Permanently Disable the Security Manager: removes the abilities to enable the Security Manager when starting the Java runtime (java
-Djava.security.manager
...) or to install a Security Manager while an application is running (System::setSecurityManager).It is worth to mention that the impacted APIs changes are going way beyond just Security Manager, notably:
- AccessController::checkPermission always throws java.security.AccessControlException
- Policy::setPolicy always throws java.lang.UnsupportedOperationException
Policy::getInstance
methods always throw java.security.NoSuchAlgorithmExceptionSecurityManager::check*
methods always throw java.lang.SecurityException- Subject::getSubject always throws java.lang.UnsupportedOperationException
- java.lang.SecurityException has been removed from most of the JDK's method signatures
JEP-483: Ahead-of-Time Class Loading & Linking: improves startup time by making the classes of an application instantly available, in a loaded and linked state, when the HotSpot Java Virtual Machine starts. Achieve this by monitoring the application during one run and storing the loaded and linked forms of all classes in a cache for use in subsequent runs. Lay a foundation for future improvements to both startup and warmup time.
This one is probably the first tangible deliverable of the Project Leyden, and an exciting one. The process to create a cache takes two steps.
First, run the application once, in a training run, to record its AOT configuration, in this case into the file
app.aotconf
:$ java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp app.jar com.example.App ...
Second, use the configuration to create the cache, in the file
app.aot
(this step doesn’t run the application, it just creates the cache):$ java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp app.jar
Subsequently, in testing or production, run the application with the cache (if the cache file is unusable or does not exist then the JVM issues a warning message and continues):
$ java -XX:AOTCache=app.aot -cp app.jar com.example.App ...
JEP-485: Stream Gatherers: enhances 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.
From the API perspective, the changes include:
- new intermediate default <R> Stream<R> gather(Gatherer<? super T, ?, R> gatherer) operation on java.util.stream.Stream that processes the elements of a stream by applying a user-defined entity called a gatherer
- new interface Gatherer<T,A,R>
- new class Gatherers, factory of implementations of Gatherer<T,A,R> that provide useful intermediate operations, such as windowing functions, folding functions, transforming elements concurrently, etc.
Please check recently published The Gatherer API tutorial for more in-depth API design overview and different usage scenarios.
The process is somewhat verbose at the moment, but no doubts, there are strong indications that the improvements are coming in the next release(s).
It was a lot but we are far from done yet, the list of preview / experimental / incubating features is as impressive:
JEP-478: Key Derivation Function API (Preview): introduces an API for Key Derivation Functions (KDFs), which are cryptographic algorithms for deriving additional keys from a secret key and other data. This is a preview API feature.
JEP-487: Scoped Values (Fourth Preview): introduces scoped values, which enable a method to share immutable data both with its callees within a thread, and with child threads. Scoped values are easier to reason about than thread-local variables. They also have lower space and time costs, especially when used together with virtual threads (JEP 444) and structured concurrency (JEP 480). This is a preview API feature.
JEP-489: Vector API (Ninth Incubator): introduces 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.
JEP-499: Structured Concurrency (Fourth Preview): simplifies 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 feature.
JEP-494: Module Import Declarations (Second Preview): enhances the Java programming language with the ability to succinctly import all of the packages exported by a module. This simplifies the reuse of modular libraries, but does not require the importing code to be in a module itself. This is a preview language feature that we have covered previously.
JEP-488: Primitive Types in Patterns, instanceof, and switch (Second Preview): enhances pattern matching by allowing primitive types in all pattern contexts, and extend instanceof and switch to work with all primitive types. This is a preview language feature that we have covered previously.
JEP-404: Generational Shenandoah (Experimental): enhances the Shenandoah garbage collector with experimental generational collection capabilities to improve sustainable throughput, load-spike resilience, and memory utilization. This experimental feature could be activated through the JVM command line options:
$ java -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational ...
JEP-450: Compact Object Headers (Experimental): reduces the size of object headers in the HotSpot JVM from between 96 and 128 bits down to 64 bits on 64-bit architectures. This will reduce heap size, improve deployment density, and increase data locality. This experimental feature could be is activated through the JVM command line options:
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders ...
JEP-492: Flexible Constructor Bodies (Third Preview): in constructors in the Java programming language, allows statements to appear before an explicit constructor invocation, i.e.,
super(..)
orthis(..)
. The statements cannot reference the instance under construction, but they can initialize its fields. Initializing fields before invoking another constructor makes a class more reliable when methods are overridden. This is a preview language feature.JEP-495: Simple Source Files and Instance Main Methods (Fourth Preview): evolves the Java programming language so that beginners can write their first programs without needing to understand language features designed for large programs. Far from using a separate dialect of the language, beginners can write streamlined declarations for single-class programs and then seamlessly expand their programs to use more advanced features as their skills grow. Experienced developers can likewise enjoy writing small programs succinctly, without the need for constructs intended for programming in the large. This is a preview language feature.
The amount of features we just looked at is astonishingly large for just one release, but let us take a look on some other fixes and improvements that went into JDK-24:
JDK-8338890: Add monitoring/management interface for the virtual thread scheduler: introduces a new JDK-specific monitoring and management interface named jdk.management.VirtualThreadSchedulerMXBean to monitor and manage the virtual thread scheduler with JMX based tooling.
JDK-8334026: Provide a diagnostic PrintMemoryMapAtExit switch on Linux: adds a new command line option
-XX:+UnlockDiagnosticVMOptions -XX:+PrintMemoryMapAtExit
to be able to get an annotated memory map at exit.JDK-8340821: Umbrella: Improve FFM Bulk Operations: an umbrella issue for a set of FFM API bulk operation improvements.
JDK-8336856: Efficient Hidden Class-Based String Concatenation Strategy: seeks to unify bootstrapping JEP-280: Indify String Concatenation expressions strategies into a single one that uses per-shape class generation emitting code semantically similar to the optimized MH expression tree.
JDK-8333867: SHA3 Performance Can be Improved: improves SHA3 performance by eliminating unnecessary conversions.
JDK-8338542 Umbrella: Reduce Startup Overhead Associated with Migration to ClassFile API: an umbrella issue for reducing startup overhead associated with migration of java.lang.invoke package to ClassFile API.
JDK-8180450: secondary_super_cache does not scale well: improvements related to better scaling of the
secondary_super_cache
.JDK-8320448: Accelerate IndexOf Using AVX2: rewrites the String::indexOf code without the use of the
pcmpestri
instruction, only using AVX2 instructions (this change accelerates String::indexOf on average 1.3x for AVX2).JDK-8343791: Socket.connect Closes the Socket If the Connection Cannot Be Established: the new
SocketImpl
introduced under JEP-353 did not close the underlying socket when theconnect
method rejected an unresolved address.JDK-8342075: HttpClient: improve HTTP/2 flow control checks: the HttpClient should report flow control issues to the server as
FLOW_CONTROL_ERROR
.JDK-8324209: Check implementation of Expect: 100-continue in the java.net.http.HttpClient: the HttpClient would previously timeout if a server didn’t respond to a request which included a
Expect: 100-Continue
header.JDK-8319993: Update Unicode Data Files to 16.0.0: support for Unicode 16.0
JDK-8333582: Update CLDR to Version 46.0: support for CLDR Version 46.
The JDK-24 tooling updates bring some new capabilities and deprecations:
JDK-8173970: jar tool should have a way to extract to a directory: The jar tool's extract operation has been enhanced to allow the
--dir
or the-C
options to be used to specify the directory where the archive will be extracted.JDK-8335912: Add an operation mode to the jar command when extracting to not overwriting existing files: the jar tool's extract operation has been enhanced to allow the
--keep-old-files
and the-k
options to be used in preventing the overwriting of existing files.JDK-8337199: Add jcmd Thread.vthread_scheduler and Thread.vthread_pollers diagnostic commands: brings two new jcmd commands:
$ jcmd <pid> Thread.vthread_scheduler
to print the virtual thread scheduler$ jcmd <pid> Thread.vthread_pollers
to print the I/O pollers that support virtual threads doing blocking network I/O operations
JDK-8327793: jstatd Is Deprecated for Removal: to reduce dependencies on RMI, the jstatd tool should be removed.
JDK-8338894: Deprecate jhsdb debugd for removal: the
debugd
subcommand of the jhsdb tool is deprecated, for removal in a future release.
Sadly, there are few regressions to be aware of that sneaked into JDK-24 release:
JDK-8350820: OperatingSystemMXBean CpuLoad() Methods Return -1.0 on Windows: on Windows, the OperatingSystemMXBean CPU load methods, such as getSystemCpuLoad, getCpuLoad, and getProcessCpuLoad, always return
-1
.JDK-8349637: IInteger.numberOfLeadingZeros outputs incorrectly in certain cases: the method Integer.numberOfLeadingZeros(int) may return an incorrect result on x86_64 with AVX2.
Last but not least, let us look over the changes to the standard library:
In scope of JDK-8341566: New Reader.of(CharSequence), one new method was introduced into java.io.Reader class:
The JDK-8336479: Provide Process.waitFor(Duration) adds a new method to java.lang.Process class:
The class java.io.Console got a few new methods:
The class java.io.IO got two new methods:
To close up, a couple of security related enhancements that deserve closer look:
JDK-8341964: Add mechanism to disable different parts of TLS cipher suite: TLS cipher suites can be disabled with the
jdk.tls.disabledAlgorithms
security property in thejava.security
configuration file using one or more'*'
wildcard characters.JDK-8319332: Security properties files inclusion: the
java.security
security properties file, and those referred to by thejava.security.properties
system property, now support including other properties files. The directiveinclude <path-to-a-file>
can be used for this purpose. Please refer to Quality Outreach Heads-up - JDK 24: Security Properties Files Inclusion for more details.
I think it is fair to say that JDK-24 is an outstanding (and at the same time, disruptive to some) release that prepares the ground for the next LTS version, JDK-25, which is expected to land later this year.
I 🇺🇦 stand 🇺🇦 with 🇺🇦 Ukraine.