01Side by side
How do Java 8, 17, 21 and 25 compare?
All four are LTS releases. Check vendor support dates on each vendor's lifecycle page.
| Area | Java 8 | Java 17 | Java 21 | Java 25 |
|---|---|---|---|---|
| Released | 2014 | September 2021 | September 2023 | September 2025 |
| Language | Lambdas, streams | Records, sealed classes, text blocks, switch expressions | Adds record patterns, pattern matching for switch | Adds more finalized preview features |
| Modules | None (classpath) | Modules, with strong encapsulation | Same as 17 | Same as 17 |
| Default GC | Parallel | G1 | G1 (ZGC generational available) | G1 |
| Concurrency | Platform threads | Platform threads | Virtual threads | Virtual threads, scoped values |
| Java EE modules in JDK | Included (JAXB, JAX-WS) | Removed | Removed | Removed |
| Spring Boot 3 | Not supported | Minimum version | Supported | Check Spring docs |
02Namespaces
What is the javax to jakarta link?
Java version and the javax to jakarta rename are separate changes that arrive together. Spring Boot 3 requires Java 17 and moves to the jakarta namespace. So a Java 8 application on Spring Boot 2 usually faces both at once. See javax to Jakarta migration and Spring Boot 3 migration.
Moving Java to 17 alone does not force the rename. You can run Spring Boot 2.7 on 17. The rename is forced when you adopt Spring Boot 3, Jakarta EE 9 or later, or a server that implements them.
03Breaks
What breaks moving from Java 8?
- 01
Java EE packages left the JDK
JAXB, JAX-WS, CORBA and some annotation packages were removed in Java 11. Add them as Maven or Gradle dependencies.
- 02
Internal APIs are sealed
Since Java 17, reflection into JDK internals fails by default. Libraries that did this need newer versions, or --add-opens flags as a stopgap.
- 03
Class loader assumptions
Code that casts the system class loader to URLClassLoader fails. Some agents and older frameworks do this.
- 04
Old libraries and bytecode tools
ASM, Byte Buddy, Mockito, Lombok, Groovy and APM agents need versions that read newer class files.
- 05
Behavior defaults
Default GC, TLS versions and some date or locale formatting differ. Tests that assert on exact output can fail.
04Smaller step
Java 17 vs 21: is it worth the second hop?
If you are on 17 already and stable, 21 adds virtual threads, pattern matching for switch and sequenced collections. None is mandatory. The case for moving is support lifetime and a framework that has dropped 17. See Java 21 features and Java 25 LTS.
If you are on Java 8, skip 17 as a destination. Plan the single move to the newest version your frameworks and vendors certify, with 17 as the fallback.
05Scoring
A quick score for your own application
Give one point for each statement that is true. This is a rule of thumb, not a measurement.
- It uses JAXB, JAX-WS or javax.annotation from the JDK.
- It uses reflection on JDK internals, directly or through a library.
- It uses bytecode agents or generation (APM, mocking, ORM weaving).
- It has fewer tests than you would trust for a refactor.
- It runs on an application server not certified for 17 or higher.
- 0 to 1: mostly a recipe run. 2 to 3: plan engineer time for fixes. 4 or more: assess before committing a date.
06Next step
How does Ace8 help?
Ace8 is the AI-assisted application modernization practice of AceMQ. Our process for a Java 8 move runs OpenRewrite recipes, then AI-assisted tools on what is left, then tests and engineer review. See the Java upgrade service.
To get the score for every application you own, book the modernization assessment.