Java 25 Upgrade Guide
Java 25 is the target runtime. This page lists the code/build changes needed, the improvements it brings, and the developer tips to get value from new language/runtime features.
What changes are required?
- Update toolchain: JDK 25 on CI/containers; set
maven.compiler.source/targetto 25. - Align Spring Boot: stay on Boot 4.x line; use matching Spring Framework 7.x and Jakarta EE 11.
- Refresh plugins: Surefire/Failsafe 3.2+, SpotBugs/PMD versions that support Java 25 bytecode.
- Check JVM flags: remove deprecated GC flags; prefer G1 or Shenandoah defaults; keep
-Xms/-Xmxsensible. - Update container base images: switch to
eclipse-temurin:25-jre(or distroless 25) and rebuild. - Test native interop: recompile JNI/FFI if any; validate TLS cert keystore formats on the new JDK.
Improvements in Java 25 to leverage
- Virtual threads (Project Loom) stabilized: simpler concurrency for request/IO-heavy code.
- Structured concurrency APIs: safer task scopes with cancellation and proper error aggregation.
- Records + pattern matching refinements: cleaner DTOs and switch expressions for domain workflows.
- Sequenced collections APIs: predictable iteration order for maps/lists in core SDK.
- GC and JIT improvements: better throughput/latency defaults; smaller GC tuning surface.
Developer tips & patterns
- Wrap blocking calls: use virtual-thread-friendly pools (
Executors.newVirtualThreadPerTaskExecutor()) where appropriate. - Use records for immutable responses/config; combine with
switchon sealed hierarchies for clearer domain logic. - Guard migrations with feature flags: roll out JVM upgrade alongside canary pods and compare SLIs.
- Update CI quality gates: enable
--enable-previewonly if needed per module; otherwise keep builds strict. - Benchmark critical paths: run JMH or k6 against representative endpoints after enabling virtual threads.