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/target to 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/-Xmx sensible.
  • 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 switch on 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-preview only if needed per module; otherwise keep builds strict.
  • Benchmark critical paths: run JMH or k6 against representative endpoints after enabling virtual threads.