Time for celebration once again: the JDK-26 was released just a few days ago! Although from all perspectives this release looks like incremental improvement (not a feature fest), it is worth paying close attention to.
JEP 500: Prepare to Make Final Mean Final: issues warnings about uses of deep reflection to mutate final fields. These warnings aim to prepare developers for a future release that ensures integrity by default by restricting final field mutation, which will make Java programs safer and potentially faster. Application developers can avoid both current warnings and future restrictions by selectively enabling the ability to mutate final fields where essential using
--enable-final-field-mutation=module1,module2,...and--illegal-final-field-mutation=allow|warn}debug|denycommand line arguments.JEP 516: Ahead-of-Time Object Caching with Any GC: enhances the ahead-of-time cache, which enables the HotSpot Java Virtual Machine to improve startup and warmup time, so that it can be used with any garbage collector, including the low-latency Z Garbage Collector (ZGC). Achieve this by making it possible to load cached Java objects sequentially into memory from a neutral, GC-agnostic format, rather than map them directly into memory in a GC-specific format.
GC-specific cached objects are mapped directly into memory, while GC-agnostic cached objects are streamed into memory. You can explicitly create a cache whose objects are in the streamable, GC-agnostic format by specifying
-XX:+AOTStreamableObjects.JEP 517: HTTP/3 for the HTTP Client API: updates the HTTP Client API to support the HTTP/3 protocol, so that libraries and applications can interact with HTTP/3 servers with minimal code change.
var client = HttpClient .newBuilder() .version(HttpClient.Version.HTTP_3) .build();Interestingly, JDK does not provide HTTP/3 server implementation (yet), however Netty library, the de facto standard in Java ecosystem for implementing high performance protocol servers (and clients), is supporting HTTP/3 in
4.2release line.JEP 522: G1 GC: Improve Throughput by Reducing Synchronization: increases application throughput when using the G1 garbage collector by reducing the amount of synchronization required between application threads and GC threads.
JEP 504: Remove the Applet API: removes the Applet API, which was deprecated for removal in JDK 17. It is obsolete because neither recent JDK releases nor current web browsers support applets.
There are a few JEPs that made into JDK-26 as preview features, all of them are carried over from the previous JDK releases.
JEP 524: PEM Encodings of Cryptographic Objects (2nd Preview): introduces an API for encoding objects that represent cryptographic keys, certificates, and certificate revocation lists into the widely-used Privacy-Enhanced Mail (PEM) transport format, and for decoding from that format back into objects. This is a preview API feature.
JEP 525: Structured Concurrency (6th Preview): simplifies concurrent programming by introducing an API for structured concurrency. Structured concurrency treats groups of related tasks running in different threads as single units of work, thereby streamlining error handling and cancellation, improving reliability, and enhancing observability. This is a preview API feature.
JEP 526: Lazy Constants (2nd Preview): introduces an API for lazy constants, which are objects that hold unmodifiable data. Lazy constants are treated as true constants by the JVM, enabling the same performance optimizations that are enabled by declaring a field final. Compared to final fields, however, lazy constants offer greater flexibility as to the timing of their initialization. This is a preview API feature.
This feature used to be known as stable values (JDK-25) and was renamed to lazy constants to better capture its intended use cases.
JEP 530: Primitive Types in Patterns, instanceof, and switch (4th 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 API feature.
JEP 529: Vector API (11th Incubator): introduces an API to express vector computations that reliably compile at runtime to optimal vector instructions on supported CPUs, thus achieving performance superior to equivalent scalar computations.
Indeed, the list of JEPs is not very impressive, but it does not make JDK-26 less important. There are quite a lot of interesting fixes and improvements in this release.
JDK-8369432: Add Support for JDBC 4.5 MR: the JDBC 4.5 MR is small update to the JDBC specification and may have an impact on compatibility with some driver implementations.
JDK-8346944: Update Unicode Data Files to 17.0.0: supports the Unicode Standard version 17.0.
JDK-8354548: Update CLDR to Version 48.0: upgrades the CLDR data in the JDK to version 48.0.
JDK-8364993: JFR: Disable jdk.ModuleExport in default.jfc: some applications with lots of code can produce an enormous number of
ModuleExportevents and associated constant pool data.JDK-8364556: JFR: Disable SymbolTableStatistics and StringTableStatistics in default.jfc: there were reports of slow response time due to these two events.
JDK-8365057: Add support for java.util.concurrent lock information to Thread.dump_to_file: the thread dump generated by the com.sun.management.HotSpotDiagnosticMXBean.dumpThreads(...) and the diagnostic command
jcmd <pid> Thread.dump_to_filenow includes information about park blocker owner for threads that are parked on java.util.concurrent.locks.AbstractOwnableSynchronizer objects.JDK-8212084: G1: Implement UseGCOverheadLimit: the G1 garbage collector now throws an OutOfMemoryError when the garbage collection overhead is more than
GCTimeLimitpercent (default value98) and the free Java heap is less thanGCHeapFreeLimitpercent (default value2) for five consecutive garbage collections. This feature is enabled by default and can be disabled using the-XX:-UseGCOverheadLimitcommand line option.JDK-8048180: G1: Eager reclaim of humongous objects with references: the G1 garbage collector now eagerly reclaims eligible humongous (very large objects that occupy more than half a heap region) objects containing references.
JDK-8325467: Support methods with many arguments in C2: the C2 JIT compiler can now compile Java methods with a large number of parameters. Previously, C2 would attempt to compile such methods but bail out, causing the JVM to fall back to C1-compiled code or the interpreter.
JDK-8366434: THP not working properly with G1 after JDK-8345655: fixes the regression introduced in JDK-25 where on systems configured with the Transparent Huge Pages (THP) mode as
madvise, the option-XX:+UseTransparentHugePagesdoes not enable huge pages when running with the default garbage collector G1. The issue preventing the option-XX:+UseTransparentHugePagesfrom enabling THP has been resolved.JDK-8371986: Remove the default value of InitialRAMPercentage: removes the default value of
InitialRAMPercentage. Now, if the user does not specify an initial Java heap size, the JVM sets the initial heap size to the minimum possible heap size, which equals toMinHeapSize. This improves startup performance for default JVM configurations by reducing internal memory initialization.JDK-8368740: Serial: Swap eden and survivor spaces position in young generation: if the heap is almost full, Serial GC will try everything to expand eden in order to satisfy the allocation request. This can cause eden size to grow beyond the limit determined by
SurvivorRatiohowever the new behavior may avoid OutOfMemoryError's in very tight heap situations that would previously often lead to JVM termination.JDK-8364638: Refactor and make accumulated GC CPU time code generic: at VM exit
-Xlog:cpunow prints a table breaking down VM CPU usage into components.[62.719s][info][cpu] === CPU time Statistics ============================================================= [62.719s][info][cpu] CPUs [62.719s][info][cpu] s % utilized [62.719s][info][cpu] Process [62.719s][info][cpu] Total 410.2789 100.00 6.5 [62.719s][info][cpu] Garbage Collection 124.8134 30.42 2.0 [62.719s][info][cpu] GC Threads 124.5082 30.35 2.0 [62.719s][info][cpu] VM Thread 0.3052 0.07 0.0 [62.719s][info][cpu] =====================================================================================JDK-8359110: Log accumulated GC and process CPU time upon VM exit: adds support to log CPU cost for GC during VM exit with
-Xlog:gc+cpu.[2,430s][info][gc,cpu] GC CPU usage: 22,87% (Process: 26,8926s GC: 6,1491s)JDK-8369346: Remove default value of and deprecate the MaxRAM flag: removes the default value of the
MaxRAMflag so that it only has an effect if a user explicitly sets it; otherwise, ergonomic heap sizing will be based solely on physical memory reported by the operating system. Additionally, theMaxRAMflag should be deprecated.JDK-8370814: Deprecate AggressiveHeap: the
AggressiveHeapflag, while intended to simplify JVM tuning for memory-intensive applications, introduces ambiguity and maintenance challenges, making it unsuitable as a general-purpose optimization option. The flag is deprecated for removal.JDK-8369238: Allow virtual thread preemption on some common class initialization paths: a virtual thread that tries to initialize a class already being initialized by another thread will now, in most cases, be unmounted from its carrier while waiting. Previously, the behavior was to pin the virtual thread to its carrier while waiting for the other thread to execute the class initializer.
JDK-8366691: JShell should support a more convenient completion: enhances the JShell API with a support for more powerful code completion for JShell snippets, suitable for GUI applications.
JDK-8330940: Impossible to create a socket backlog greater than 200 on Windows 8+: setting the connection backlog to a value greater than
200in java.net.ServerSocket, java.nio.channels.ServerSocketChannel, and java.nio.channels.AsynchronousServerSocketChannel is now effective on Windows. Previously it was clamped at200.JDK-8370057: Correct scale handling of BigDecimal.sqrt: changes the preferred scale of java.math.BigDecimal#sqrt to align with IEEE 754.
JDK-8363972: Lenient parsing of minus sign pattern in DecimalFormat/CompactNumberFormat: the java.text.NumberFormat now allows implementations to parse the minus sign in negative patterns leniently when in lenient mode (java.text.NumberFormat#isStrict() returns
false).JDK-8357653: Inner classes of type parameters emitted as raw types in signatures: fixes the issue when the code that names an inner class is erroneously classified as raw and as a result is erroneously rejected (example below).
static abstract class Getters<T> { abstract class Getter { abstract T get(); } } static class Usage<T, G extends Getters<T>> { public T test(G.Getter getter) { return getter.get(); // incompatible types: Object cannot be converted to T } }JDK-8369517: Compilation mismatch for equivalent lambda and method reference: fixes the Java compiler behavior when a capture conversion should be applied when deciding if a method reference is compatible with a given function type.
interface Main { interface X>T< { X>T< self(); } static X>?< makeX() { return null; } static >R< X>R< create(Supplier>? extends R< supplier) { return null; } static X>X>?<< methodRef() { return create(Main::makeX).self(); } static X>X>?<< lambda() { return create(() -> makeX()).self(); // incompatible types: } }JDK-7105350: HttpExchange's attributes are the same as HttpContext's attributes: fixes an issue when the com.sun.net.httpserver.HttpExchange attribute map was shared with the enclosing com.sun.net.httpserver.HttpContext.
JDK-8362561: Remove diagnostic option AllowArchivingWithJavaAgent: some old CDS tests cases use Java agents during
java -Xshare:dumpexecution for injecting Java agents and require the diagnostic-XX:+AllowArchivingWithJavaAgentcommand line option which can sometimes be abused and produce undesirable side effects.
For more elaborate overview of GC changes, please refer to JDK 26 G1/Parallel/Serial GC changes blog post. Besides just JEP 517, the java.net.http.HttpClient got quite a lot of attention in this JDK release, certainly worth highlighting separately.
JDK-8367112: HttpClient does not support Named Groups set on SSLParameters: during the setup of new connections, java.net.http.HttpClient now uses the signature schemes and named groups configured on java.net.ssl.SSLParameters when negotiating the TLS handshake. Previously these configured values were ignored.
JDK-8358942: HttpClient adds Content-Length: 0 for a GET request with a BodyPublishers.noBody(): java.net.http.HttpClient has been updated to stop sending the
Content-Lengthheader on HTTP/1.1 requests using a HTTP methods other thanPOSTorPUTwhen provided with a HttpRequest.BodyPublisher that reports a contentLength() of zero bytes.JDK-8351983: HttpCookie Parser Incorrectly Handles Cookies with Expires Attribute: the java.net.HttpCookie has been updated to correctly handle cookies with both
ExpiresandMax-Ageattributes.JDK-8208693: HttpClient: Extend the request timeout's scope to cover the response body: the java.net.http.HttpClient request timeout set via java.net.http.HttpRequest.Builder::timeout(...) previously applied only until the response headers were received. Its scope has now been extended to also cover the consumption of the response body, if present.
JDK-8329829: HttpClient: Add a BodyPublishers.ofFileChannel method: add a new static ofFileChannel(FileChannel channel, long offset, long length) method to java.net.HttpRequest.BodyPublishers to allow an java.net.http.HttpClient request body publisher to upload a certain region of a file.
Also, java.net.http.HttpRequest got a new method:
Another notable changes in JDK include:
JDK-8366575: Remove SDP support: InfiniBand SDP (Sockets Direct Protocol) has been obsolete for more than a decade and is no longer maintained on any major platform, and cannot be used on modern systems.
JDK-8332623: Remove setTTL()/getTTL() methods from DatagramSocketImpl/MulticastSocket and MulticastSocket.send(DatagramPacket, byte): removes the following terminally deprecated methods from java.net.MulticastSocket:
public void setTTL(byte ttl) throws IOExceptionpublic byte getTTL() throws IOExceptionpublic void send(DatagramPacket p, byte ttl) throws IOException
and the following terminally deprecated methods from java.net.DatagramSocketImpl
protected void setTTL(byte ttl) throws IOExceptionprotected byte getTTL() throws IOException
JDK-8356557: Update CodeSource::implies API documentation and deprecate java.net.SocketPermission class for removal: deprecates java.net.SocketPermission for removal and removes dependencies on java.net.SocketPermission from java.security.CodeSource#implies(...).
JDK-8366577: Deprecate java.net.Socket::setPerformancePreferences: deprecates the method
setPerformancePreferencesin java.net.Socket, java.net.SocketImpl, and java.net.ServerSocket for removal without any replacement.JDK-8368226: Remove Thread.stop: removes
java.lang.Thread#stop()method.JDK-8370387: Remove handling of InterruptedIOException from java.io classes: removes uses of java.io.InterruptedIOException from relevant classes in its package (the class java.io.InterruptedIOException is problematic and is targeted for deprecation and eventual removal).
JDK-8364361: [process] java.lang.Process should implement Closeable: the addition of java.lang.Process#close() and the implementation of java.io.Closeable and java.lang.AutoCloseable interfaces to java.lang.Process allow for consistent and reliable cleanup.
JDK-8362448: Make use of the Double.toString(double) algorithm in java.text.DecimalFormat: by using the same algorithm used by java.lang.Double#toString() and java.util.Formatter, the behavior of java.text.DecimalFormat becomes aligned with these and produce comparable outcomes.
JDK-8362637: Convert java.nio.ByteOrder to an enum: converts java.nio.ByteOrder to an enum for use in switch expressions.
JDK-8334015: Add Support for UUID Version 7 (UUIDv7) defined in RFC 9562: adds a static factory method java.util.UUID#ofEpochMillis(long) to create Version 7 UUIDs as defined in RFC 9562, embedding the supplied Unix time in milliseconds.
JDK-8368527: JMX: Add an MXBeans method to query GC CPU time: adds a new method to java.lang.management.MemoryMXBean to return the accumulated CPU time in nanoseconds for GC related activity.
JDK-8365675: Add String Unicode Case-Folding Support: adds Unicode standard-compliant case-less comparison methods to the java.lang.String class, enabling and improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
JDK-8368856: Add a method that performs saturating addition of a Duration to an Instant: adds new java.time.Instant#plusSaturating(Duration) method.
JDK-8366829: Add java.time.Duration constants MIN and MAX: adds to java.time.Duration two new constants MIN and MAX.
JDK-8356995: Provide default methods min(T, T) and max(T, T) in Comparator interface: new default methods java.util.Comparator#min(...) and java.util.Comparator#max(...) have been added to the java.util.Comparator interface, which allow finding greater or smaller of two objects (according to this comparator).
In addition, java.math.BigInteger got two new methods:
This is pretty much it but we haven't talked about security related changes, it is just about time.
JDK-8343232: PKCS#12 KeyStore support for RFC 9879: Use of Password-Based Message Authentication Code 1 (PBMAC1): the support of a new stronger MAC algorithm for PKCS#12 defined in RFC 9879 has been implemented.
JDK-8349732: Add support for JARs signed with ML-DSA: adds support for JARs signed with ML-DSA, based on IETF RFC 9882.
JDK-8325448: Hybrid Public Key Encryption: implement HPKE (Hybrid Public Key Encryption) as defined in RFC 9180 in the form of a JCE javax.crypto.Cipher.
JDK-8244336: Restrict algorithms at JCE layer: creates a new security property
jdk.crypto.disabledAlgorithmsthat restricts crypto algorithms at the JCE layer.JDK-8359956: Support algorithm constraints and certificate checks in SunX509 key manager: supports TLS algorithm constraints and certificate checks in
SunX509key manager which is currently the default key manager.JDK-8361964: Remove outdated algorithms from requirements and add PBES2 algorithms: removes the following algorithms from the list of required algorithms as they are no longer recommended, and should not be in wide usage anymore:
AlgorithmParameters: DESede Cipher: DESede/CBC/NoPadding DESede/CBC/PKCS5Padding DESede/ECB/NoPadding DESede/ECB/PKCS5Padding RSA/ECB/PKCS1Padding KeyGenerator: DESede SecretKeyFactory: DESedeAdd the following PBES2 algorithms from PKCS#5 v2.1 as new requirements:
AlgorithmParameters: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 Cipher: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 Mac: PBEWithHmacSHA256 SecretKeyFactory: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 PBKDF2WithHmacSHA256JDK-8359395: XML signature generation does not support user provided SecureRandom: adds a new javax.xml.crypto.dsig.XMLSignContext property named
jdk.xmldsig.SecureRandomso that users can provide their own java.security.SecureRandom object when generating an XML signature.JDK-8353749: Improve security warning when using JKS or JCEKS keystores: the tools and java.security.KeyStore APIs have been updated to warn users when legacy JKS and JCEKS keystores are used, as they use outdated cryptographic algorithms and will be removed in a future release.
JDK-8351354: Enhance java -XshowSettings:security:tls to show enabled TLS groups: the output of
-XshowSettings:security:tlscommand line option has been updated to include the list of enabled named groups and the list of enabled signature schemes used for SSL/TLS/DTLS handshakes.JDK-8366364: Return enabled signature schemes with SSLConfiguration#getSSLParameters() call: also enhances
-XshowSettings:security:tlscommand line option to show the enabled signature schemes.JDK-8371259: ML-DSA AVX2 and AVX512 intrinsics and improvements: delivers new intrinsics using AVX2 instructions on x86_64 platforms for the ML-DSA signature algorithm in the SUN security provider. This feature also improves the existing AVX512 intrinsics for the ML-DSA algorithm. This optimization is enabled by default on supporting x86_64 platforms and may be disabled by providing the
-XX:+UnlockDiagnosticVMOptions -XX:-UseDilithiumIntrinsicscommand line options.
If you look for a bit more in-depth overview of the security related changes, please check out JDK 26 Security Enhancements blog post.
To summarize, the gems of JDK-26 release, in my opinion, are JEP 522: G1 GC: Improve Throughput by Reducing Synchronization, JEP 517: HTTP/3 for the HTTP Client API, and JDK-8369238: Allow virtual thread preemption on some common class initialization paths. Those are truly game changing enhancements for quite a wide audience of applications and services. Java continues to impress!
I πΊπ¦ stand πΊπ¦ with πΊπ¦ Ukraine.


