JDK 26 Early-Access Release Notes

This is a draft of the release notes that will accompany JDK 26. The contents are subject to change until release.

Build 22

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.

Build 21

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.

Build 20

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.

Build 18

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 instead of as the cause of the NoSuchAlgorithmException.

Build 17

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.

Default initial heap size is trimmed down (JDK-8348278)

hotspot/gc

When user does not specify -Xms, JVM ergonomics guesses the initial heap size, based on InitialRAMPercentage setting, currently set at 1/64 of physical RAM. The initial heap size drives the startup times, because GCs need to initialize their internal data structures, e.g. remsets, card tables, or even heap memory itself for the initial heap. This heuristics had not changed for decades, and modern computers ship with much larger system memories, which initializes a very large initial heap.

This release trims InitialRAMPercentage to 0.2, improving the startup time for default JVM modes. In case this change causes any problems, users are advised to either specify more reasonable Xms explicitly, or override the InitialRAMPercentage setting.

Build 16

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.

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

security-libs/java.security

A new security property jdk.crypto.disabledAlgorithms has been introduced to disable algorithms for JCE/JCA cryptographic services. Initially this property only supports 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.

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.

Build 14

MBeanServer registerMBean Exception Correction (JDK-8364227)

core-svc/javax.management

The javax.management.MBeanServer method registerMBean is changed to throw 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.

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.

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

core-libs/java.lang.classfile

In the class file format, many integer values use a more narrow representation than that representable by the int primitive type in the Java programming language. Currently, in the Class-File API, users can provide int values that will truncate upon write to class file, which means the value won't be preserved when read.

To prevent such error-prone usage, the Class-File API now performs eager validation of such int values, 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.

Build 13

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

Build 12

javax.imageio.stream classes no longer support Java Object Finalization (JDK-8277585)

client-libs

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 consequently 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 3rd 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 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 3rd 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.

Add Dark Theme to API Documentation (JDK-8342705)

tools/javadoc(tool)

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.

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.

Build 10

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 (no checking of local certificates) of the "SunX509" key manager 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).

Build 9

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

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

Build 8

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.

Build 7

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; } });
}

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

core-svc/javax.management

The classes javax.management.AttributeList, and javax.management.relation.RoleList and UnresolvedRoleList, have historicallly 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.

Build 6

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, which it would have been an error for code outside the package to have used for its own purposes.

Build 5

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.

Build 3

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.

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.