Welcome to the final OpenJDK Quality Outreach update of 2025!
JDK 26, scheduled for General Availability on March 17, 2026, is now
in Rampdown Phase One[1]. At this stage, the overall JDK 26 feature
set is frozen, and only low-risk enhancements may still be considered.
I would like to thank the projects that raised issues addressed in
this release: JUnit, jOOQ, PDFBox, and Maven.
You will find below the list of JEPs integrated into JDK 26. One JEP
that stands out is JEP 517, which introduces HTTP/3 support to the
HTTP Client API. Supporting HTTP/3 is an important advancement. It
should also be noted that adding this feature to the platform was a
significant undertaking; the HTTP/3 pull request is the largest
OpenJDK PR in recent years. The JDK Networking team encourages you to
try out this new feature (see the related Heads-up below). Another JEP
that stands out is JEP 504, as the Applet API has finally been removed
from the platform. We do not expect this to cause any disruption, as
applets are no longer used and this change was announced well in
advance. For more background on this effort, please refer to this
article[2].
Looking ahead, the next milestone is in early February, when the first
JDK 26 Release Candidate builds will be available. This means we have
a few weeks, excluding the end-of-year break, to identify and
hopefully address any issues your projects might encounter. If you
experience any problems with the JDK early-access builds, please let
us know as soon as possible.
I will conclude this update with a quick note on JavaOne, as
registration has just opened. If you plan to attend J1, please let me
know. It would be great to meet in person and discuss the Quality
Outreach program.
[1] https://mail.openjdk.org/pipermail/jdk-dev/2025-December/010662.html
[2] https://inside.java/2025/12/03/applet-removal/
# Heads-Up - JDK 26: HTTP/3 Support in HTTP Client API
JEP 517 introduces support for HTTP/3 in the HTTP Client API. While
HTTP/3 offers similar features to HTTP/2 at the protocol level, its
key distinction is that it runs over the QUIC protocol using UDP,
whereas HTTP/2 and HTTP/1.1 operate over TCP.
If your code requests HTTP/3 but it is not available, the client will
downgrade to HTTP/2 or HTTP/1.1 instead. However, if your code tries
to enforce HTTP/3 exclusively, a failed attempt will result in an
exception.
For the first request to a server, the client tries both HTTP/2 (TCP)
and HTTP/3 (UDP) and uses whichever connects first. Subsequently,
HttpClient uses the “Alt-Svc” mechanism to learn which protocols the
server supports, so future requests can use HTTP/3 if supported. For
additional details, be sure to check these resources[3][4].
## Call to Action
Although the enhancements to the HTTP Client API appear simple on the
surface, supporting HTTP/3 on top of QUIC is the result of several
years of dedicated development effort by the JDK Networking team. As
this implementation is still new, we encourage you to download the JDK
26 early-access builds, try out this feature, and share your feedback
on the net-dev[5] mailing list (registration required).
[3] https://inside.java/2025/10/30/quality-heads-up/
[4] https://inside.java/2025/10/22/http3-support/
[5] https://mail.openjdk.org/mailman/listinfo/net-dev
# Heads-Up - JDK 26: HttpClient Supports TLS Named Groups & Signature
Schemes
Java applications can configure TLS constraints on
`javax.net.ssl.SSLParameters` during the setup of new connections.
However, until now, HttpClient ignored the named groups and signature
schemes set on SSLParameters. Starting with JDK 26,
`java.net.http.HttpClient` preserves the signature schemes and named
groups configured via SSLParameters when negotiating the TLS
handshake. For more information, check this resource[6].
[6] https://inside.java/2025/11/26/quality-heads-up/
# Heads-Up - JDK 25: Consistent Behavior of 'new File("")'
On JDK 24 and earlier, the behavior of a `File` instance created from
an empty string (e.g., `var file = new File("")`) was inconsistent.
When queried using methods like `file.exists()` and
`file.isDirectory()`, it appeared to be non-existent because both
returned false. Similarly, methods such as `canRead()` returned false,
while `length()`, `lastModified()`, etc. returned 0.
When transformed into an instance representing the absolute path
(e.g., `var file = new File("").getAbsoluteFile()`), the behavior
changes: the previously mentioned methods now return meaningful
results. This is because `new File("").getAbsoluteFile()` maps to the
current user directory, and the File API behaves accordingly. Since
both `new File("")` and `new File("").getAbsoluteFile()` should
represent the same file system entry, this inconsistency is jarring
and can be surprising.
The newer API in `java.nio.file` avoids this issue and treats both
`Path.of("")` and `Path.of("").toAbsolutePath()` as the current user
directory. For example, both `Files.exists(Path.of(""))` and
`Files.exists(Path.of("").toAbsolutePath())` return true.
JDK 25 fixed this long-standing inconsistency: `new File("")` now
properly represents the current user directory, so for `var file = new
File("")`, methods like `file.exists()` and `file.isDirectory()`
return true. The `File` Javadoc[7] was updated to spell out the
intended behavior.
For more details, check JDK-8024695[8].
## Call To Action
Code that relies on the old behavior is often found in unit tests
(e.g., to intentionally create non-existent files with `new File("")`)
or in cases where user input is mapped to file system entries (e.g.,
to treat "no user entry" and "invalid user entry" the same: as an
absent file. In such cases, the change may manifest as issues related
to file arguments or configuration.
While fixing such code should be straightforward, identifying it may
not be, so a thorough test suite is helpful. For dependencies and
tools, it is recommended to rely on their tests and statements
regarding JDK 25 compatibility, as only they can address potential
issues. There is no way to restore the inconsistent behavior of JDK 24
and earlier.
[7]
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/io/File.html
[8] https://bugs.openjdk.org/browse/JDK-8024695
# JDK 26 Early-Access Builds
The JDK 26 early-access builds 27 are available[9]. You can review the
Release Notes here[10].
## JEPs integrated into JDK 26:
- JEP 500: Prepare to Make Final Mean Final
- JEP 504: Remove the Applet API
- JEP 516: Ahead-of-Time Object Caching with Any GC
- JEP 517: HTTP/3 for the HTTP Client API
- JEP 522: G1 GC: Improve Throughput by Reducing Synchronization
- JEP 524: PEM Encodings of Cryptographic Objects (2nd Preview)
- JEP 525: Structured Concurrency (6th Preview)
- JEP 526: Lazy Constants (2nd Preview)
- JEP 529: Vector API (11th Incubator)
- JEP 530: Primitive Types in Patterns, instanceof, and switch (4th
Preview)
## Changes in recent JDK 26 builds that may be of interest:
- JDK-8208693: HttpClient: Extend the request timeout's scope to cover
the response body
- JDK-8365675: Add String Unicode Case-Folding Support
- JDK-8371470: Java Launcher does not fail when running compact
java-file with private no-arg constructor
- JDK-8251928: [macos] the printer DPI always be 72, cause some
content lost when print out
- JDK-8268613: jar --validate should check inital entries of a JAR file
- JDK-8366424: Missing type profiling in generated Record Object methods
- JDK-8347831: Re-examine version check when cross linking
- JDK-8373023: Remove the default value of InitialRAMPercentage
- JDK-8325448: Hybrid Public Key Encryption
- JDK-8353749: Improve security warning when using JKS or JCEKS keystores
- JDK-8371259: ML-DSA AVX2 and AVX512 intrinsics and improvements
- JDK-8346944: Update Unicode Data Files to 17.0.0
- JDK-8368527: JMX: Add an MXBeans method to query GC CPU time
- JDK-8371960: Missing null check in AnnotatedType annotation accessor
methods
- JDK-8349732: Add support for JARs signed with ML-DSA
- JDK-8354548: Update CLDR to Version 48.0
- JDK-8369517: Compilation mismatch for equivalent lambda and method
reference
- JDK-8370813: Deprecate AggressiveHeap
- JDK-8370843: Deprecate AlwaysActAsServerClassMachine and
NeverActAsServerClassMachine
- JDK-8366577: Deprecate java.net.Socket::setPerformancePreferences
- JDK-8212084: G1: Implement UseGCOverheadLimit
- JDK-8368856: Add a method that performs saturating addition of a
Duration to an Instant
- JDK-8343232: Support for PBMAC1 protection on PKCS12 keystores
- JDK-8369346: Remove default value of and deprecate the MaxRAM flag
- JDK-8362637: Convert java.nio.ByteOrder to an enum
- JDK-8369238: Allow virtual thread preemption on some common class
initialization paths
- JDK-8364361: [process] java.lang.Process should implement Closeable
- JDK-8334015: Add Support for UUID Version 7 (UUIDv7) defined in RFC
9562
- JDK-8366575: Remove SDP support
- JDK-8370387: Remove handling of InterruptedIOException from java.io
classes
- JDK-7105350: HttpExchange's attributes are the same as HttpContext's
attributes
- JDK-8370057: Correct scale handling of BigDecimal.sqrt
- JDK-8358942: HttpClient adds Content-Length: 0 for a GET request
with a BodyPublishers.noBody()
Note: A more exhaustive list of changes can be found here[11].
[9] https://jdk.java.net/26/
[10] https://jdk.java.net/26/release-notes
[11] https://github.com/openjdk/jdk/compare/jdk-26+20...jdk-26+27
# Valhalla Early-Access Builds
Project Valhalla early-access builds implementing JEP 401 (Value
Classes and Objects (Preview)) are available[12]. The goal of these
builds is to establish a milestone and solicit feedback as we work
toward integrating this functionality into the JDK. More information
can be found in the feature documentation[13], in this article[14],
and in this video[15]. Feedback can be sent to the valhalla-dev
mailing[16] list (registration required).
[12] https://jdk.java.net/valhalla/
[13] https://openjdk.org/projects/valhalla/value-objects
[14] https://inside.java/2025/10/27/try-jep-401-value-classes/
[15] https://youtu.be/Eua3nTkye2Y
[16] https://mail.openjdk.org/mailman/listinfo/valhalla-dev
# JavaFX Direct3D 12 Early-Access Builds
The early-access JavaFX builds implementing the new Direct3D 12
graphics rendering pipeline for Windows x64 are now available[17]. The
goal of this EA build is to solicit feedback as we work toward
integrating this functionality into JavaFX. Feedback can be sent to
the openjfx-dev[18] mailing list (registration required).
[17] https://jdk.java.net/javafxdirect3d12/
[18] https://mail.openjdk.org/mailman/listinfo/openjfx-dev
# Topics of Interest
- All Features in Java 26 - Inside Java Newscast
https://inside.java/2025/12/04/newscast-102/
- Java 26 Warns of Deep Reflection - Inside Java Newscast
https://inside.java/2025/11/20/newscast-101/
- HTTP/3 Support in JDK 26
https://inside.java/2025/10/22/http3-support/
- So Long and Thanks for All the Applets
https://inside.java/2025/12/03/applet-removal/
- “From Cowboy Mode to Careful Stewardship” with Mark Reinhold -
Inside Java Podcast
https://inside.java/2025/10/27/podcast-041/
- “Amber & Valhalla - Incremental Design and Feature Arcs” with Brian
Goetz - Inside Java Podcast
https://inside.java/2025/09/28/podcast-040/
- Value Classes Heap Flattening - What to expect from JEP 401 #JVMLS
https://inside.java/2025/10/31/jvmls-jep-401/
- Help, My Java Object Vanished (and the GC is Not at Fault)
https://arraying.de/posts/markword/
- Symbolic Modeling and Transformation of Java Code #JVMLS
https://inside.java/2025/11/22/jvmls-symbolic-modelling-java-transformation/
- Beyond the Vector API - A Quest for a Lower Level API #JVMLS
https://inside.java/2025/11/16/jvmls-vector-api/
- Serialization 2.0: A Marshalling Update!
https://inside.java/2025/11/10/devoxxbelgium-serialization2-0-marshalling-update/
- Pulling the (Foreign) String
https://cr.openjdk.org/~mcimadamore/panama/strings_ffm.html
- NUMA-Aware Relocation in ZGC
https://joelsiks.com/posts/zgc-numa-aware-relocation/
- Garbage Collection in Java: Choosing the Correct Collector
https://inside.java/2025/11/29/devoxxbelgium-choose-correct-gc/
- Evolving ZGC's Pointer Color Palette #JVMLS
https://inside.java/2025/10/06/jvmls-zgc-colored-pointers/
- Three Upcoming G1 Improvements
https://inside.java/2025/10/23/newscast-99/
- JDK 25 Security Enhancements
https://seanjmullan.org/blog/2025/09/23/jdk25
- Performance Improvements in JDK 25
https://inside.java/2025/10/20/jdk-25-performance-improvements/
~
As always, ping me if you find any issues while testing your
project(s) with the latest JDK early-access builds. And as the
year-end is fast approaching, let me wish you all the best for the
upcoming holidays. See you in 2026 with Java 26, Java 27, and
hopefully some of you in person at JavaOne 2026!
PS: Please let me know if you don't want to receive these OpenJDK
Quality Outreach updates anymore.
--David