JDK 26 Release Notes

Features

500: Prepare to Make Final Mean Final

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

504: Remove the Applet API

Remove the Applet API, which was deprecated for removal in JDK 17 (2021). It is obsolete because neither recent JDK releases nor current web browsers support applets.

516: Ahead-of-Time Object Caching with Any GC

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

For more information: JEP 516: Ahead-of-Time Object Caching with Any GC
517: HTTP/3 for the HTTP Client API

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

522: G1 GC: Improve Throughput by Reducing Synchronization

Increase application throughput when using the G1 garbage collector by reducing the amount of synchronization required between application threads and GC threads.

524: PEM Encodings of Cryptographic Objects (Second Preview)

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

525: Structured Concurrency (Sixth Preview)

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

526: Lazy Constants (Second Preview)

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

529: Vector API (Eleventh Incubator)

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

530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview)

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

Contents

HttpContext attributes no longer shared with HttpExchange by default (JDK-7105350)

core-libs/java.net

Prior to JDK 26, in the JDK default implementation of the HTTP server in the jdk.httpserver module, the HttpExchange attribute map was shared with the enclosing HttpContext.

Since JDK 26, by default, context attributes are no longer shared with all of their exchanges. Instead each exchange has its own map of attributes. This default behavior can be reverted to the pre JDK 26 behavior by setting the "jdk.httpserver.attributes" system property.

See the jdk.httpserver module-info for more information.

Virtual Threads Now Unmount from Carrier When Waiting for Another Thread to Execute a Class Initializer (JDK-8369238)

hotspot/runtime

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.

This change may improve performance in some cases, as unmounting from the carrier releases a platform thread, allowing the JDK virtual thread scheduler to mount a different virtual thread.

The change also helps address the pathological case where all platform threads available to the JDK virtual thread scheduler are pinned by virtual threads waiting for another thread to execute a class initializer. If the thread executing the class initializer blocks or waits on something that requires a virtual thread to execute, the system could become deadlocked, as no virtual thread would be able to continue execution.

New Features

Endpoint Identification Enabled by Default for RMI Connections over TLS (JDK-8341496 (not public))

core-libs/java.rmi

RMI will use TLS connections if the javax.rmi.ssl.SslRMIClientSocketFactory ????? class is used. These connections now have TLS endpoint identification enabled by default. This may cause some previously-working TLS connections to fail. If this occurs, ensure that the certificate presented by the server has a Subject Alternative Name that matches the server's hostname. Alternatively, endpoint identification for RMI TLS connections can be disabled on the client side by setting the jdk.rmi.ssl.client.enableEndpointIdentification system property to false.

Enhanced keytool Password Handling When Output Is Redirected (JDK-8354469)

security-libs/java.security

The keytool command reads passwords from the system console to prevent them from being displayed on the screen. However, the console is usually available only when both the standard input and output streams are not redirected. Previously, if the standard output stream was redirected into a file or another command, the console was unavailable and the input password was echoed on the screen. This enhancement improves password handling to ensure that the password is not displayed on the screen even if the standard output stream is redirected. This enhancement has also been made to the jarsigner command and the JAAS TextCallbackHandler API.

java.lang.Process Implements AutoCloseable and Closeable (JDK-8364361)

core-libs/java.lang

Process ????? has a new close() method and supports AutoCloseable ?????. Closing a process ensures that it has terminated and its streams and underlying resources are released. When used with try-with-resources, the process and its streams are closed when the try-with-resources block exits.

See java.lang.Process ????? for details and examples.

Support for Unicode 17.0 (JDK-8346944)

core-libs/java.lang

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

For more details about Unicode 17.0, refer to the Unicode Consortium’s release note.

Listening Sockets Now Accept Connection Backlog Greater Than 200 on Windows (JDK-8330940)

core-libs/java.net

Setting the connection backlog to > 200 in java.net.ServerSocket, java.nio.channels.ServerSocketChannel, and java.nio.channels.AsynchronousServerSocketChannel is now effective on Windows. Previously it was clamped at 200.

Server applications that use a higher backlog value will now queue more incoming connections, at the operating system level, rather than rejecting the connection.

New ofFileChannel Method in java.net.http.HttpRequest.BodyPublishers to Upload Region of a File (JDK-8329829)

core-libs/java.net

A new static ofFileChannel(FileChannel channel, long offset, long length) ????? method has been added to java.net.HttpRequest.BodyPublishers. This method provides an HttpClient request body publisher to upload a certain region of a file. The new publisher does not modify the state of the passed FileChannel, streams the file channel bytes as it publishes (i.e., avoids reading the entire file into the memory), and can be leveraged to implement sliced uploads.

Add JDBC 4.5 MR Support (JDK-8369432)

core-libs/java.sql

JDK 26 includes support for the JDBC 4.5 MR. That MR provides the following updates to the JDBC Specification:

This update may have an impact on compatibility with some JDBC driver implementations:

  • If there is an internal, that is private or protected, implementation of the newly added default methods, the implementation will need to either be renamed or made public
  • A class cannot implement multiple interfaces that provide different default implementations of the same method. Implementations of these interfaces may need to override the default methods to resolve the ambiguity.

Lenient Parsing of Minus Sign Pattern in DecimalFormat/CompactNumberFormat (JDK-8363972)

core-libs/java.text

java.text.NumberFormat ????? now supports lenient parsing of minus signs in negative patterns when NumberFormat.isStrict() ????? returns false. This behavior is enabled by default and can be disabled with NumberFormat.setStrict(true) ?????. When lenient, the concrete implementations, DecimalFormat ????? and CompactNumberFormat ?????, use CLDR's parseLenient data to recognize alternate minus signs. For example, text using the MINUS SIGN (U+2212) as the negative prefix is now correctly parsed:

jshell> var num = NumberFormat.getNumberInstance().parse("u22123")
num ==> -3

java.time.Duration Minimum and Maximum Values (JDK-8366829)

core-libs/java.time

New constants are added to java.time.Duration for the minimum and maximum values. Duration.MIN is the smallest (negative) duration and Duration.MAX is the largest (positive) duration.

Adding a Duration to an Instant with Saturation (JDK-8368856)

core-libs/java.time

java.time.Instant has a new method to simplify adding a Duration to an Instant. The plusSaturating(Duration) method adds a Duration to an Instantusing saturating arithmetic. The method never overflows or exceeds the Instant range, and returns the nearest bound(Instant.MINorInstant.MAX`) instead of throwing an exception.

Added Support for Creating a Type 7 UUID (UUIDv7) (JDK-8334015)

core-libs/java.util

java.util.UUID.ofEpochMillis(long) ????? has been added to create a type 7 UUID from a given Unix epoch timestamp.

New Method MemoryPoolMXBean.getTotalGcCpuTime() (JDK-8368527)

core-svc/java.lang.management

A new method getTotalGcCpuTime() ????? has been added to java.lang.management.MemoryMXBean ?????, that returns a long result with the accumulated CPU time in nanoseconds for GC related activity.

Although added as a standard API, possible usage may be in conjunction with the ProcessCpuTime property defined by the JDK-specific management interface com.sun.management.OperatingSystemMXBean ?????.

JEP 516: Ahead-of-Time Object Caching with Any GC ( JEP 516)

hotspot/gc

Enhance 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).

Prior to JEP 516: Ahead-of-Time Object Caching with Any GC, some of the AOT optimizations of the AOT cache from project Leyden, introduced in JDK 24 by JEP 483: Ahead-of-Time Class Loading & Linking, did not work when using ZGC. The state of objects could not be cached due to memory mapping the object state bit by bit from a file into the heap, which requires a common object format. The advanced memory layout of ZGC was incompatible with the simpler object format used by other GC implementations.

JEP 516 introduces a new way of loading objects in the background, instead of directly memory mapping a file, which is compatible across all GC implementations. Hence, the full range of optimizations of the AOT cache is now available across all GC implementations, including ZGC.

G1: Support UseGCOverheadLimit (JDK-8212084)

hotspot/gc

The G1 garbage collector now throws an OutOfMemoryException when the garbage collection overhead is more than GCTimeLimit percent (default value 98) and the free Java heap is less than GCHeapFreeLimit percent (default value 2) for five consecutive garbage collections.

This feature is enabled by default. It can be disabled using the -XX:-UseGCOverheadLimit option.

The implementation mirrors the functionality already provided by the Parallel garbage collector. However there may be differences in the exact conditions for the OOME triggers as G1 calculates garbage collection overhead and free Java heap slightly differently.

Eager Reclaim of Humongous Objects with References for G1 (JDK-8048180)

hotspot/gc

The G1 garbage collector now eagerly reclaims eligible humongous (very large objects that occupy more than half a heap region) objects containing references. Instead of requiring liveness analysis (concurrent marking) of the entire Java heap, G1 can collect these objects at any garbage collection pause if they are not referenced any more.

This mechanism applies to both humongous arrays of references (e.g. Object[]) and regular humongous objects.

This change allows for prompt recovery of memory previously held by such objects, particularly if they are short-lived. This improves garbage collection efficiency and reduces heap usage.

Thread Dumps Generated by HotSpotDiagnosticMXBean.dumpThreads and jcmd Thread.dump_to_file Updated to Include Owner of the Park Blocker (JDK-8365057)

hotspot/svc

The thread dump generated by the com.sun.management.HotSpotDiagnosticMXBean.dumpThreads API, and the diagnostic command jcmd <pid> Thread.dump_to_file, now includes information about park blocker owner for threads that are blocked for parking on java.util.concurrent.locks.AbstractOwnableSynchronizer objects.

Signed JAR Support for ML-DSA (JDK-8349732)

security-libs/java.security

The JDK now supports creating and verifying JAR files signed with the post-quantum ML-DSA algorithm, using PKCS #7 as defined in RFC 9882. This new feature is available through both the JarSigner API and the jarsigner tool.

New Security Property jdk.crypto.disabledAlgorithms for Restricting Algorithms at the JCE layer (JDK-8244336)

security-libs/java.security

A new security property named jdk.crypto.disabledAlgorithms has been introduced to disable algorithms for JCE/JCA cryptographic services. Initially, this property only supports the Cipher, KeyStore, MessageDigest, and Signature services. This property is defined in the java.security file and initially no algorithms are disabled by default. However, this may change in the future. This security property can be overridden by a system property of the same name if applications need to re-enable algorithms.

See Disabled and Restricted Cryptographic Algorithms for more information.

Hybrid Public Key Encryption (JDK-8325448)

security-libs/javax.crypto

A new Cipher algorithm named "HPKE" has been introduced. The HPKE algorithm is defined in RFC 9180: Hybrid Public Key Encryption and is a public key encryption scheme for encrypting arbitrary-sized plaintexts with a recipient's public key. HPKE combines a key encapsulation mechanism (KEM), a key derivation function (KDF), and an authenticated encryption with additional data (AEAD) cipher. All KEM, KDF, and AEAD algorithm identifiers defined in RFC 9180 are supported.

The new HPKEParameterSpec class allows users to choose algorithm identifiers and set other parameters such as HPKE modes, application-supplied info, and mode-specific keys. The API documentation ????? provides a simple example showing how to set parameters and perform encryption and decryption.

See Securely Exchanging Messages with HPKE and the HPKEParameterSpec Class for more information.

Support Algorithm Constraints and Certificate Checks in SunX509 Key Manager (JDK-8359956)

security-libs/javax.net.ssl

The default "SunX509" KeyManagerFactory for TLS now supports the same algorithm constraints and certificate check functionality as the "PKIX" KeyManagerFactory. Selection and prioritization of the local certificates chosen by the KeyManager is based on the following checks:

  1. Local certificates are checked against peer supported certificate signature algorithms sent with the signature_algorithms_cert TLS extension.
  2. Local certificates are checked against TLS algorithm constraints specified in the jdk.tls.disabledAlgorithms and jdk.certpath.disabledAlgorithms security properties.
  3. Local certificates are prioritized based on validity period and certificate extensions.

The legacy behavior of the "SunX509" key manager, no checking of local certificates, can be restored by setting the jdk.tls.SunX509KeyManager.certChecking system property to false.

User-specified SecureRandom Object in XML Signature Generation (JDK-8359395)

security-libs/javax.xml.crypto

A new property called "jdk.xmldsig.SecureRandom" has been added to DOMSignContext ????? so you can use your own SecureRandom instance. To use this property, call signContext.setProperty("jdk.xmldsig.SecureRandom", yourSecureRandom) before calling XMLSignature.sign(signContext).

Dark Theme to API Documentation Added (JDK-8342705)

tools/javadoc(tool)

The API documentation generated by JavaDoc ????? now features a dark theme. The theme can be switched between the default light theme, the new dark theme, and the theme indicated by the system setting using the new theme button in the navigation bar.

Removed Features and Options

Removed Four AffirmTrust Root Certificates (JDK-8361212)

security-libs/java.security

The following root certificates, which are deactivated and no longer in use, have been removed from the cacerts keystore:

+ alias name "affirmtrustcommercialca [jdk]"
  Distinguished Name: CN=AffirmTrust Commercial, O=AffirmTrust, C=US

+ alias name "affirmtrustnetworkingca [jdk]"
  Distinguished Name: CN=AffirmTrust Networking, O=AffirmTrust, C=US

+ alias name "affirmtrustpremiumca [jdk]"
  Distinguished Name: CN=AffirmTrust Premium, O=AffirmTrust, C=US

+ alias name "affirmtrustpremiumeccca [jdk]"
  Distinguished Name: CN=AffirmTrust Premium ECC, O=AffirmTrust, C=US

javax.imageio.stream Classes No Longer Support Java Object Finalization (JDK-8277585)

client-libs/javax.imageio

Java Object Finalization will be removed from a future JDK version. In anticipation of this, use of this mechanism has been removed from the class javax.imageio.stream.ImageInputStreamImpl ????? and from all its subclasses.

This should have no impact on almost all applications, since no JDK provided Image I/O code needed the finalization mechanism. Applications which use third party Image plugins may be affected in extremely specific cases where those plugins may fail to flush the stream and relied on finalization. However, that is further limited to applications which use FileCacheImageOutputStream ????? or MemoryFileCacheImageOutputStream (link not found), since these are the only stream types that would need flushing. It should also be noted that if the application itself is relying on finalization to flush the stream, then it cannot know when it may safely close the stream and so very likely has a bug.

Another scenario is a third party ImageIO stream which acquires native resources. If the application is relying on finalization to release these, it may need to be updated to explicitly close the ImageIO stream. However, this is also a case in which, if the application is not doing this already, it is may be saving truncated streams.

Thread.stop Is Removed (JDK-8368226)

core-libs/java.lang

The method java.lang.Thread.stop() has been removed in this release. This inherently unsafe method was deprecated in JDK 1.2 (1998), deprecated for removal in JDK 18, and was re-specified in JDK 20 to throw UnsupportedOperationException unconditionally. Code that uses this method will no longer compile. Code using this method that is compiled to older releases will throw NoSuchMethodError instead of UnsupportedOperationException if executed on JDK 26 or newer.

Removal of DatagramSocketImpl.setTTL()/getTTL(), MulticastSocket.setTTL()/getTTL(), and MulticastSocket.send(DatagramPacket, byte) Methods (JDK-8332623)

core-libs/java.net

The following terminally deprecated methods have been removed:

java.net.MulticastSocket methods:

public void setTTL(byte ttl) throws IOException
public byte getTTL() throws IOException
public void send(DatagramPacket p, byte ttl) throws IOException 

java.net.DatagramSocketImpl methods:

protected void setTTL(byte ttl) throws IOException
protected byte getTTL() throws IOException

Support for InfiniBand Sockets Direct Protocol (SDP) Has Been Removed (JDK-8366575)

core-libs/java.net

The JDK built-in support for InfiniBand Sockets Direct Protocol (SDP) on Linux has been removed. SDP has been obsolete for many years and is no longer supported by any mainstream distribution.

The system property com.sun.sdp.conf that could be used to configure SDP usage, and the sample configuration file $JAVA_HOME/conf/sdp/sdp.conf.template, are also removed.

Unicode Normalization Format D Property Is No Longer Supported (macOS) (JDK-8366911)

core-libs/java.nio

Normalization of file names is not performed by APFS, which succeeded HFS+ as the macOS file system as of September 2017. The system property jdk.nio.path.useNormalizationFormD was added in JDK 20 to allow enabling such normalization if it was needed for backward compatibility. Given that no currently supported version of macOS performs file path normalization, support for this property has been removed.

Remove XML Interchange in java.management/javax/management/modelmbean/DescriptorSupport (JDK-8351413)

core-svc/javax.management

The deprecated XML interchange feature in javax.management.modelmbean.DescriptorSupport ????? is removed, meaning the constructor DescriptorSupport(String inStr) and the method toXMLString() are removed. Also the class javax.management.modelmbean.XMLParseException is removed, for which it would have been an error for code outside the package to have used for its own purposes.

The jdk.jsobject Module Has Been Removed (JDK-8359760)

other-libs

The jdk.jsobject module has been removed - it is included with JavaFX 24 and later.

Removed DESede and PKCS1Padding Algorithms from Requirements and Added PBES2 Algorithms (JDK-8361964)

security-libs/java.security

The following security algorithm implementation requirements in the Java Security Standard Algorithm Names specification and the API specifications have been removed 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: DESede

The following PBES2 algorithms from RFC 8018: PKCS #5: Password-Based Cryptography Specification Version 2.1 have been added as new requirements:

AlgorithmParameters:
    PBEWithHmacSHA256AndAES_128
    PBEWithHmacSHA256AndAES_256
Cipher:
    PBEWithHmacSHA256AndAES_128
    PBEWithHmacSHA256AndAES_256
Mac:
    PBEWithHmacSHA256
SecretKeyFactory:
    PBEWithHmacSHA256AndAES_128
    PBEWithHmacSHA256AndAES_256
    PBKDF2WithHmacSHA256

jrunscript Tool Removed (JDK-8367157)

tools

The experimental and unsupported jrunscript tool has been removed from the JDK.

Deprecated Features and Options

SocketPermission Class Deprecated for Removal (JDK-8356557)

core-libs/java.net

The java.net.SocketPermission ????? class has been deprecated for removal. This permission cannot be used for controlling access to resources as the Security Manager is no longer supported.

Deprecated java.net.Socket::setPerformancePreferences for Removal (JDK-8366577)

core-libs/java.net

The method setPerformancePreferences in java.net.Socket, java.net.SocketImpl, and java.net.ServerSocket was introduced in Java 1.5 with the intention of providing a declarative API for configuring the performance-wise characteristics of the underlying socket, yet it has always been a no-op. These methods are deprecated for removal without any replacement.

Deprecate the MaxRAM Flag (JDK-8369346)

hotspot/gc

To simplify heap sizing and reduce user confusion, the MaxRAM flag has been marked as deprecated with the intent to be obsoleted and removed in future releases. Explicit configuration of MaxRAM is rarely necessary, as the JVM accurately detects available physical memory and system commit limits. Setting MaxRAM above the actual physical memory may lead to incorrect heap sizing and is not a common use case.

Additionally, the default value of MaxRAM has been removed. From now on and until the MaxRAM flag is obsoleted, heap sizing calculations are based on the available memory on the system rather than the default value of MaxRAM, unless MaxRAM is explicitly set by the user.

Users who need to control the heap size directly are encouraged to use flags such as -Xms and -Xmx instead.

Deprecate the AlwaysActAsServerClassMachine and NeverActAsServerClassMachine Flags (JDK-8370843)

hotspot/gc

The AlwaysActAsServerClassMachine and NeverActAsServerClassMachine flags are used to influence two separate behaviors: 1) which GC is chosen by default, and 2) to influence whether client emulation mode is selected. Both flags have been marked as deprecated with the intent to be obsoleted and removed in future releases.

Users who rely on a specific GC being chosen through the AlwaysActAsServerClassMachine and NeverActAsServerClassMachine flags should instead explicitly configure the GC they want, for example by using -XX:+UseSerialGC or -XX:+UseG1GC.

Client emulation mode was used to emulate a client build on platforms with reduced virtual address space, mainly Windows 32-bit (see JDK-8166002). With Windows 32-bit being deprecated in JDK 24 (see JEP 479), the incentive for maintaining the client emulation mode feature is gone, and thus also the method to influence whether it is enabled is no longer needed.

When the flags are obsoleted and removed, users will no longer be able to influence whether client emulation mode is enabled via the NeverActAsServerClassMachine flag.

Deprecate the AggressiveHeap Flag (JDK-8370813)

hotspot/gc

The AggressiveHeap flag was originally introduced to optimize performance for specific benchmarking scenarios, but its lack of transparency and limited applicability have led to confusion and inconsistent results for general workloads. To simplify JVM configuration and encourage users to explicitly select tuning options that best fit their application needs, this flag has now been marked as deprecated with the intent to be removed in future releases.

Users who require their application to continue with similar behavior should specify the corresponding flags:

-XX:+UseParallelGC -XX:+UseLargePages -XX:-ResizeTLAB -XX:TLABSize=256K -XX:YoungPLABSize=256K -XX:OldPLABSize=8K -XX:ThresholdTolerance=100

and set the following values:

  • -Xmx and -Xms to half the available physical memory
  • -XX:NewSize to 3/8 of available physical memory
  • -XX:MaxNewSize to the value of -XX:NewSize

Notable Issues Fixed

HttpClient Now Supports Configuring TLS Named Groups and Signature Schemes (JDK-8367112)

core-libs/java.net

During the setup of new connections, java.net.http.HttpClient now uses the signature schemes and named groups configured on SSLParameters when negotiating the TLS handshake. Previously these configured values were ignored.

Support C2 Compilation of Methods with Large Numbers of Parameters (JDK-8325467)

hotspot/compiler

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. This change enables applications to benefit from C2 optimizations for a wider range of methods, improving performance. No application changes are required to take advantage of this improvement.

-XX:+UseTransparentHugePages Again Enables Transparent Huge Pages for G1 (JDK-8366434)

hotspot/gc

G1, the default garbage collector, can again properly utilize Transparent Huge Pages (THP) on systems with the THP mode configured as madvise.

The issue preventing the option -XX:+UseTransparentHugePages from enabling THP has been resolved.

Inner Classes of Type Parameters Emitted As Raw Types in Signatures (JDK-8357653)

tools/javac

Whenever a reference to an inner type of the kind A.B is found, javac needs to normalize the qualifier type A, so that any reference to potentially parameterized types are made explicit. This normalization occurs regardless of whether this type is explicitly provided in the source code, or inferred from the enclosing context. Some cases were found where no normalization was applied to the type qualifier -- e.g. if the qualifier is a type-variable type. The lack of normalization led to spurious errors, as the type reference was incorrectly classified as a raw type. This change adds the missing normalization step. While this change is generally beneficial, as spurious errors that would cause compilation to fail are no longer generated, there might be cases where the additional normalization steps might result in a change in overload resolution.

For example, assume the following snippet in which the result of the getter.get() method call is passed to an overloaded method with two candidates: m(T) and M(Object). Without the patch the following code prints Object, erroneously; with the patch the following code prints T, correctly. An erroneous classification of the qualified type means that the type G.Getter was treated as a raw type and the result of the method call was Object; the correct classification is to treat it as T <: Number and the return type of the method call to be Number. That very classification selects a different overload m before and after the patch:

static class Usage<T extends Number, G extends Getters<T>> {
    public void test(G.Getter getter) {
        m(getter.get()); // javac selects one of the overloads for m
    }
    void m(T t)       { System.out.println("T");   }
    void m(Object s)  { System.out.println("Object");  }
}

static abstract class Getters<T> {
    abstract class Getter {
        abstract T get();
    }
}

public static void main(String[] args) {
    new Usage<Integer, Getters<Integer>>().test(new Getters<Integer>() {}.new Getter() { Integer get() { return 42; } });
}

Other Notes

PKCS12 KeyStore Support for RFC 9879: Use of Password-Based Message Authentication Code 1 (PBMAC1) (JDK-8343232)

security-libs/java.security

The JDK PKCS12 KeyStore ????? implementation now supports the more modern PBMAC1 algorithm for integrity protection. To use the PBMAC1 algorithm, set the "keystore.pkcs12.macAlgorithm" property in the java.security configuration file to a PBMAC1 algorithm. For example, "PBEWithHmacSHA256". Existing PKCS12 keystore files will continue to use the integrity algorithm it was created with, but new keystore files will use the PBMAC1 algorithm.

In a future JDK release, the default value of the "keystore.pkcs12.macAlgorithm" security property will be changed to a PBMAC1 algorithm.

PrintStream and PrintWriter Mark Stream in Error if Write Fails with InterruptedIOException (JDK-8370387)

core-libs/java.io

The behavior of java.io.PrintStream ????? and java.io.PrintWriter ????? has changed when writing to a custom output stream that throws InterruptedIOException. If the custom output stream's write method throws InterruptedIOException, then the PrintStream or PrintWriter is now marked in error so that checkError returns true. Historically, this exception caused the writing Thread's interrupted status to be set, without marking the stream in error.

Class-File API Rejects Unrepresentable Integer Data (JDK-8361614, JDK-8361635)

core-libs/java.lang.classfile

In the class file format, the representable range of many integer values are narrower than that of the int primitive type in the Java programming language. Currently, the Class-File API truncates the most significant bytes of a user-provided int value upon writing to class file. Upon reading, the truncated value is zero or sign extended, depending on the type, back to an int, and may differ from the user-provided value. For instance, an int value 65536 would become 0 after this write-read to a u2 value .

To prevent such error-prone usage, the Class-File API now performs eager validation of int values that would be lost after a truncation, including the size of lists. Such unrepresentable data will result in an IllegalArgumentException. Users who used such silent truncation should migrate to explicit truncation before passing data instead.

AnnotatedType Throws NullPointerException for null Arguments (JDK-8371960)

core-libs/java.lang:reflect

Annotation access methods declared on java.lang.reflect.AnnotatedElement ????? specify they throw NullPointerException if their argument is null. In prior releases, implementations of java.lang.reflect.AnnotatedType ????? and its subinterfaces did not throw NullPointerException for isAnnotationPresent ?????, getAnnotation ?????, and getDeclaredAnnotation ????? methods from AnnotatedElement. These methods now throw NullPointerException instead of returning false or null for a null argument.

Implementation of java.net.CookieStore.getURIs() and get(URI) Methods Now Return an Immutable List (JDK-8365086)

core-libs/java.net

The JDK's implementation of the java.net.CookieStore interface has been updated to return an immutable java.util.List from the getURIs() and get(URI) methods. The updated implementation now matches the specification of these two methods.

Extend the HTTP Client Request Timeout to Cover the Response Body (JDK-8208693)

core-libs/java.net

The HTTP Client request timeout set using 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.

HttpClient No Longer Sends the Content-Length Header on Requests With No Body (JDK-8358942)

core-libs/java.net

java.net.HttpClient has been updated to stop sending the Content-Length header on HTTP/1.1 requests using a method ????? other than POST or PUT when provided with a BodyPublisher that reports a contentLength() of zero bytes.

This behavior follows the recommendations in RFC 9110: HTTP Semantics.

Users who need the header may add it using the HttpRequest Builder. The header is restricted by default, and needs to be allowed by setting the system property jdk.httpclient.allowRestrictedHeaders ????? to include content-length.

HttpCookie Handles Conflicting Expires and Max-Age Attributes (JDK-8351983)

core-libs/java.net

java.net.HttpCookie has been updated to correctly handle cookies with both Expires and Max-Age attributes. RFC 6265 specifies that the Max-Age attribute should take precedence over the Expires attribute if both are present in the same cookie. This behavior change is reflected in the HttpCookie.getMaxAge method.

BodyPublishers.ofFile Is Changed to Throw FileNotFoundException Consistently (JDK-8358688)

core-libs/java.net

Previously, java.net.http.HttpRequest.BodyPublishers::ofFile(Path) ????? could throw java.nio.file.NoSuchFileException when the provided Path was not associated with the default file system. This inconsistency has been removed by mapping these to java.io.FileNotFoundException, in line with the ofFile API specification.

Convert java.nio.ByteOrder to an Enum (JDK-8362637)

core-libs/java.nio

java.nio.ByteOrder ????? is converted from a class to an Enum to allow it to be used in expression switch and elsewhere the language can dispatch on an Enum, for example in switch. The ByteOrder enum is fully compatible with the class implementation. The BIG_ENDIAN, LITTLE_ENDIAN, and ByteOrder.nativeOrder() ????? values remain a simple and effective way to test for the byte order.

java.text.DecimalFormat Now Uses the Double.toString(double) Algorithm (JDK-8362448)

core-libs/java.text

Class java.text.DecimalFormat ????? now uses the algorithm implemented in Double.toString(double) ????? and in java.util.Formatter ????? to format floating-point values.

As a consequence, in rare cases the outcome might be slightly different than with the old algorithm. For example, the double 7.3879E20 now produces "738790000000000000000" rather than "738790000000000100000" given appropriate formatting specifications.

To help migrating applications that might be impacted by this change, for a few releases the old algorithm will still be available to DecimalFormat ????? and classes that depend on it, like NumberFormat ?????. The old algorithm can be enabled with the "-Djdk.compat.DecimalFormat=true" option on the launcher command line. Absent this option, the new algorithm is used.

Support for CLDR Version 48 (JDK-8354548)

core-libs/java.util:i18n

The locale data based on the Unicode Consortium's CLDR has been upgraded to version 48. Besides the usual addition of new locale data and translation changes, there are notable changes from the upstream CLDR, affecting Date/Time/Number formats:

CLDR-16439 zone alias South_Pole was moved to McMurdo, so remove it from Auckland (#4592)

CLDR-16665 key/type core values (#4577)

CLDR-13688 Correct the first day of week for Iceland from Monday to Sunday (#4379)

CLDR-18464 Add a Before Hijrah era to the Islamic calendars (#4581)

CLDR-18572 Add more European Englishes (#4645)

CLDR-18253 Add en_JP (#4634)

CLDR-18603 Add GyM, GyMEd availableFormats to root, en (#4679)

CLDR-18538 root,en: change H patterns without m[s] to add literal 'h' (#4708)

CLDR-9814 Recover Turkey metazone names (#4741)

CLDR-18788 Fix Russian metazones (#4833)

CLDR-13542 Fix Swiss grouping separator (#5019)

Note that locale data is subject to change in a future release of the CLDR. Although not all locale data changes affect the JDK, users should not assume stability across releases. For more details, please refer to the Unicode Consortium's CLDR release notes and their locale data deltas.

JDWP Specification Fixes with Regards to OPAQUE_FRAME and INVALID_SLOT Error Codes (JDK-8362304)

core-svc/debugger

StackFrame.SetValues ?????, StackFrame.GetValues ?????, StackFrame.PopFrames ?????, and ThreadReference.ForceEarlyReturn ????? all received specification updates to clarify when OPAQUE_FRAME and INVALID_SLOT errors are returned.

(1) The JDWP specification for StackFrame.GetValues did not mention OPAQUE_FRAME as a possible error, but it is possible. The specification has been updated to include language regarding when OPAQUE_FRAME can be returned.

(2) The JDWP specification for StackFrame.SetValue only mentioned OPAQUE_FRAME as a possible error for virtual threads, indicating that the operation is not possible on the specified frame. However, OPAQUE_FRAME is possible for other reasons, such as the frame being native. The specification has been updated to adopt the more general description of when OPAQUE_FRAME can be returned.

(3) The JDWP specification StackFrame.PopFrames and ThreadReference.ForceEarlyReturn was too specific with regards to when OPAQUE_FRAME can be returned. The specification has been updated to adopt the more general description of when OPAQUE_FRAME can be returned.

(4) The JDWP specification for StackFrame.SetValue failed to mention INVALID_SLOT as a possible error result. This has been fixed.

JDI Specification Clarifications and Implementation Changes Regarding when OpaqueFrameException and NativeMethodException Are Thrown (JDK-8309400)

core-svc/debugger

ThreadReference.popFrames() ????? and ThreadReference.forceEarlyReturn() ????? were previously documented as only throwing OpaqueFrameException for virtual threads. This indicated that the functionality cannot be performed on the virtual thread frame for a reason that is unique to virtual threads.

However, it was realized that there were error conditions that resulted in a NativeMethodException when in fact the underlying error was not due to a native method, and was not unique to virtual threads. The appropriate exception in this case would be an OpaqueFrameException instead of a NativeMethodException.

Both these APIs have now been updated to be consistent with when these two exceptions are thrown for both virtual threads and platform threads. This means you may now see these two APIs throw OpaqueFrameException for a platform thread when previously this was not possible.

MBeanServer registerMBean Exception Correction (JDK-8364227)

core-svc/javax.management

The javax.management.MBeanServer method registerMBean ????? now throws a RuntimeOperationsException instead of NullPointerException when invoked with a null "object" parameter. This correction aligns the implementation with the specification, and becomes the same as other methods in the class. This is not expected to affect most applications, and could only be noticed after other application errors have occurred.

AttributeList, RoleList, and RoleUnresolvedList Should Never Accept Other Types of Object (JDK-8359809)

core-svc/javax.management

The classes javax.management.AttributeList ?????, and javax.management.relation.RoleList ????? and RoleUnresolvedList ?????, have historically accepted objects of the wrong type, and only verified types when (and after) the "asList()" method is called. This feature has been removed, and these classes never accept the wrong kind of Object. Most applications using these classes should not be affected.

JMXServiceURL Requires an Explicit Protocol (JDK-8347114)

core-svc/javax.management

The class javax.management.remote.JMXServiceURL ????? requires that a protocol is specified when using its String constructor, and will throw MalformedURLException if the protocol is missing. This behaviour is now extended to the other constructors that take individual parameters, and the historical defaulting to the "jmxmp" protocol is removed.

Default Initial Heap Size Now Set to MinHeapSize (JDK-8371986)

hotspot/gc

If users do not specify the initial Java heap size using -Xms or -XX:InitialHeapSize, the Java Virtual Machine's (JVM) memory management decides the initial Java heap size using the InitialRAMPercentage setting. The default has been 1/64 of the system's physical RAM. This behavior results in large initial Java heap sizes on modern systems with a substantial amount of memory, increasing JVM startup times due to necessary initialization of Java heap-related internal data structures.

This change 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 to MinHeapSize. This improves startup performance for default JVM configurations by reducing internal memory initialization.

To get the previous behavior, users can explicitly set InitialRAMPercentage to the original value of 1.5625, or configure the initial Java heap size directly using the -Xms or -XX:InitialHeapSize options.

Serial: Expand Eden Space Beyond SurvivorRatio (JDK-8368740)

hotspot/gc

The size of eden and survivor spaces inside of a young generation is governed by SurvivorRatio. These sizes can change whenever the young generation size is updated.

After this change, 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 SurvivorRatio.

This new behavior may avoid OutOfMemoryExceptions in very tight heap situations that would previously often terminate the VM.

JVMTI Specification Clarified when OPAQUE_FRAME Is Thrown for Reasons Other Than a Native Method (JDK-8309399)

hotspot/jvmti

The following JVMTI spec sections have been updated to be made more clear and consistent with regards to which cases the JVMTI_ERROR_OPAQUE_FRAME error code can be returned: PopFrame, NotifyFramePop, ForceEarlyReturn<Type>, GetLocal<Type>, SetLocal<Type>, and the description of the JVMTI_ERROR_OPAQUE_FRAME error code.

Deallocate jmethodID Native Memory (JDK-8268406)

hotspot/runtime

The internal representation of native method pointers, jmethodID, has been changed to no longer be a pointer to the JVM representation of the method. Native code that breaks the abstraction of jmethodID to assume this representation will stop working in JDK 26. jmethodID is now a unique identifier that the JVM maps to the native JVM Method.

Distrust TLS Server Certificates Anchored by Chunghwa Root Certificates and Issued After March 17, 2026 (JDK-8369282)

security-libs/java.security

The JDK will stop trusting TLS server certificates issued after March 17, 2026 and anchored by Chunghwa root certificates, in line with similar plans announced by Google and Mozilla.

TLS server certificates issued on or before March 17, 2026 will continue to be trusted until they expire. Certificates issued after that date, and anchored by the Certificate Authority listed in the table below, will be rejected.

The restrictions are enforced in the JDK implementation (the SunJSSE Provider) of the Java Secure Socket Extension (JSSE) API. A TLS session will not be negotiated if the server's certificate chain is anchored by any of the Certificate Authorities in the table below and the certificate has been issued after March 17, 2026.

An application will receive an exception with a message indicating the trust anchor is not trusted, for example:

"TLS Server certificate issued after 2026-03-17 and anchored by a distrusted legacy Chunghwa root CA: OU=ePKI Root Certification Authority, O="Chunghwa Telecom Co., Ltd." C=TW"

The JDK can be configured to trust these certificates again by removing "CHUNGHWA_TLS" from the jdk.security.caDistrustPolicies security property in the java.security configuration file.

The restrictions are imposed on the following Chunghwa Root certificates included in the JDK:

Root Certificates distrusted after 2026-03-17
Distinguished Name SHA-256 Fingerprint
OU=ePKI Root Certification Authority, O="Chunghwa Telecom Co., Ltd.", C=TW

C0:A6:F4:DC:63:A2:4B:FD:CF:54:EF:2A:6A:08:2A:0A:72:DE:35:80:3E:2F:F5:FF:52:7A:E5:D8:72:06:DF:D5

You can also use the keytool utility from the JDK to print out details of the certificate chain, as follows:

keytool -v -list -alias <your_server_alias> -keystore <your_keystore_filename>

If any of the certificates in the chain are issued by one of the root CAs in the table above are listed in the output you will need to update the certificate or contact the organization that manages the server.

Tools and KeyStore APIs Warn If JKS or JCEKS Keystores Are Used (JDK-8353749)

security-libs/java.security

The tools and 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. Users are instead advised to migrate to a PKCS12 keystore using the keytool -importkeystore command.

The following changes have been made:

  • The existing warning emitted by keytool ????? has been updated to warn of the removal of the JKS and JCEKS keystores.
  • jarsigner ????? has been updated to emit a warning when a JKS or JCEKS keystore is used.
  • The KeyStore.load() ????? and KeyStore.store() ????? APIs have been updated to emit a debug warning when operating on a JKS or JCEKS keystore and -Djava.security.debug=keystore is enabled.

All warnings inform the user that JKS and JCEKS use outdated cryptographic algorithms and will be removed in a future release. Users are advised to migrate to a PKCS12 keystore.

Filter Rules for URIs in the Authority Info Access Extension for Certificates (JDK-8368032 (not public))

security-libs/java.security

A new system and security property, com.sun.security.allowedAIALocations, has been introduced. This property allows users the ability to define one or more filtering rules to be applied to URIs obtained from the authority info access extension on X.509 certificates. These filter rules are applied specifically to the CA issuers access method. Any CA issuers URIs in X.509 certificates are only followed when the com.sun.security.enableAIAcaIssuers system property is enabled and the filter allows the URI.

In order to set the rules, the user must set either the com.sun.security.allowedAIALocations security property or the system property by the same name. If the system property has a value, it will override the security property. By default the property is blank, which enacts a deny-all ruleset.

For either property, the value consists of a set of space-separated rules that take the form of a URI, with the following constraints:

  • The URI must be absolute and hierarchical.
  • The URI must only use one of the following schemes: http, https, ldap, or ftp (case-insensitive).
  • A hostname or address must be specified and must match (case-insensitive). No name resolution is performed on hostnames to match URIs with IP addresses.
  • The port number must match. Where a port number is omitted, the well-known port will be used in the comparison.
  • For hierarchical schemes (https (link not found), ftp):
    • A rule's normalized path portion of the URI is matched in a case-sensitive manner. If the final component does not end in a slash (/), it is considered to be a file path and must match the CA issuer URI path component. If the rule's path component ends in a slash, then it must match or be a prefix of the CA issuer URI path component. (for example, a filter path of /ab/cd/ will match a CA issuer path of /ab/cd/, /ab/cd/ef and /ab/cd/ef/ghi.).
    • Query strings and fragments will be ignored when matching CA issuer URIs.
  • For ldap URIs:
    • The base DN must be an exact match (case-insensitive).
    • Any query string in the rule, if specified, will be ignored.

For the properties, a single value of "any" (case-insensitive) will create an allow-all rule.

ML-DSA AVX2 and AVX512 Intrinsics and Improvements (JDK-8371259)

security-libs/javax.crypto

This feature 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. It may be disabled by providing the -XX:+UnlockDiagnosticVMOptions -XX:-UseDilithiumIntrinsics command-line options.

Cipher.getInstance(String) Now Throws NoSuchPaddingException Instead of Wrapping It Inside a NoSuchAlgorithmException (JDK-8360463)

security-libs/javax.crypto

The Cipher.getInstance(String) ????? method is declared to throw NoSuchPaddingException and NoSuchAlgorithmException. In prior releases, NoSuchPaddingException is never thrown and is instead wrapped inside a NoSuchAlgorithmException as the cause. This issue has been fixed and NoSuchPaddingException is thrown directly.

-XshowSettings:security:tls Includes Named Groups and Signature Schemes (JDK-8351354, JDK-8366364, JDK-8371074)

security-libs/javax.net.ssl

The output of java -XshowSettings:security:tls has been updated to include the list of enabled named groups and the list of enabled signature schemes used for SSL/TLS/DTLS handshakes.

Disable XPath in XML Signatures (JDK-8314180)

security-libs/javax.xml.crypto

XML signatures that use XPath transforms have been disabled by default. The XPath transform is not recommended by the XML Signature Best Practices document. Applications should use the XPath Filter 2.0 transform instead, which was designed to be an alternative to the XPath transform. If necessary, and at their own risk, applications can workaround this policy by modifying the jdk.xml.dsig.secureValidationPolicy security property and re-enabling the XPath transform. See the definition of this security property in the java.security file for more information.

Compilation Mismatch for Equivalent Lambda and Method Reference (JDK-8369517)

tools/javac

Prior to JDK 26, the javac compiler did not apply a JLS mandated capture conversion when deciding if a method reference is compatible with a given function type. This could lead the javac compiler to accept code like the following:

    import java.util.function.Supplier;

    class Test {
        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(Test::makeX).self();
        }
    }

Starting from JDK 26, the javac compiler will apply the JLS mandated capture conversion when deciding if a method reference is compatible with a given function type. Code, like that in the sample above, will be rejected.

Stricter Version Checking When Using jlink Tool to Cross Link (JDK-8347831)

tools/jlink

The jlink ????? tool can be used to assemble a set of modules and their dependences into a custom runtime image for a different OS, architecture, or JDK version to the JDK containing the jlink tool. This is sometimes referred to as "cross linking".

The version checking used when cross linking is changed to be more strict than in previous releases. When cross linking, the set of standard and JDK modules for the custom runtime must exactly match the version and vendor of the JDK containing the jlink tool. This strict checking is necessary due to the pipeline of jlink plugins that transform and optimize the classes and resources that go into the image. The jlink tool cannot reliably generate a run-time image when they don't match exactly.

In previous releases the version checking was less strict and allowed jlink running on JDK $N.0.$U from vendor $X create a run-time image from a set of modules for JDK $N.0.$V from vendor $Y. The strict checking means that the value of $U and $V must be equal, and that $X and $Y be equal.

Java Source Launcher Rejects Programs with a Private No-arg Constructor (JDK-8371470)

tools/launcher

The Java launcher ????? now rejects source programs with a private no-arg constructor, which matches what the Java launcher does in normal class mode.

FEATURE_SECURE_PROCESSING for XPath (JDK-8356294 (not public))

xml/jaxp

The JDK XPath implementation now supports External Access Properties. It also enables restriction through these properties when secure processing is set to true explicitly. To secure an XPath processor against risky evaluation of external DTD references, enable secure processing as demonstrated in the following code:

    XPathFactory xf = XPathFactory.newInstance();
    xf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

This process will cause the XPath processor created via the factory to throw XPathExpressionException if used to evaluate a raw XML document that contains external references such as an external DTD.

Mitigation includes using the External Access Properties to override that enabled by FSP. For example, the following setting will allow the process to continue when there is a reference to a file-based external DTD in the XML document:

    xf.setProperty(ACCESS_EXTERNAL_DTD, "file");

It is recommended that applications use the XPath processor to evaluate DOM rather than raw XML documents.

See (The FEATURE_SECURE_PROCESSING Security Directive)https://docs.oracle.com/en/java/javase/26/security/java-api-xml-processing-jaxp-security-guide.html#GUID-B38FA75E-7452-4881-B2C2-5E668BF77334 (link not found) and (External Access Properties)https://docs.oracle.com/en/java/javase/26/security/java-api-xml-processing-jaxp-security-guide.html#GUID-94ABC0EE-9DC8-44F0-84AD-47ADD5340477 (link not found) for more information.