Why Spring Boot 3 Completely Drops JDK 8
Spring Boot 3 raises its minimum Java version to 17 because Spring Framework 6 moves to Jakarta EE 9+, ending support for the javax.* namespace, and Oracle stopped free updates for JDK 8, making migration essential for security, ecosystem compatibility, and to leverage new language features and Spring‑Boot‑specific improvements.
Incompatibility of Spring Boot 3 with JDK 8
Spring Boot 3 is built on Spring Framework 6, which requires Jakarta EE 9+. The package rename from javax.* to jakarta.* makes the runtime impossible on JDK 8.
Why JDK 8 Must Be Dropped
1. JDK 8 Is Technically Obsolete
Oracle stopped free public updates for JDK 8 in January 2019, so security patches require commercial support or third‑party builds (e.g., Adoptium, Amazon Corretto).
New language features such as Records, Sealed Classes, and Pattern Matching are unavailable.
The broader ecosystem (Spring, Hibernate, Tomcat 10+) has already moved forward.
2. Jakarta EE Namespace Change
After Java EE was donated to the Eclipse Foundation in 2017, the javax.* namespace had to be changed to jakarta.*. Core APIs (Servlet, JPA, Validation) changed their package names, and Spring Boot 3 bundles Tomcat 10+ and Hibernate 6, which only recognize the Jakarta namespace. The old javax.servlet classes no longer exist.
3. Maintaining Dual Code Paths Is Unsustainable
Supporting both javax and jakarta would double the test matrix and require duplicate bug fixes, an unrealistic burden for a framework of Spring’s size.
4. JDK 17 Chosen Over JDK 11
Both JDK 11 and JDK 17 are LTS, but JDK 17 includes the features added after 11 (Records, Sealed Classes, Text Blocks, etc.). Choosing 17 gives developers a “one‑time upgrade, many‑year stability” guarantee.
Key Features Introduced in JDK 17
Records – immutable data classes that reduce boilerplate.
Text Blocks – multi‑line string literals without explicit \n concatenation.
Sealed Classes – restrict the inheritance hierarchy.
Pattern Matching for instanceof – automatic cast eliminates manual casting.
These features are usable out‑of‑the‑box in a Spring Boot 3 project.
Spring Boot 3 New Capabilities
Native Image Support (GraalVM)
Compiling a Spring Boot application to a native executable reduces startup time from seconds to milliseconds and dramatically lowers memory consumption, making it suitable for serverless or container‑dense deployments.
Virtual Threads (Spring Boot 3.2+, JDK 21)
Project Loom’s virtual threads can be enabled with a single property, eliminating complex thread‑pool tuning while keeping code identical to synchronous style.
Observability Enhancements
Micrometer Observation automatically configures tracing and metrics, integrating smoothly with Zipkin, Prometheus, and similar tools.
Declarative HTTP Interface Client
Define an interface with @HttpExchange and method‑level annotations; Spring generates the client, removing the need for manual RestTemplate or Feign configuration.
Spring Security 6 Rewrite
Security now fully aligns with Jakarta EE, offering updated OAuth2 and JWT configurations and stronger defaults.
Practical Code Samples
Record DTO
public record UserResponse(Long id, String username, String email) {} @RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public UserResponse getUser(@PathVariable Long id) {
return new UserResponse(1L, "zhangsan", "[email protected]");
}
}Declarative HTTP Client
@HttpExchange("/api/posts")
public interface PostClient {
@GetExchange("/{id}")
Post getPost(@PathVariable Long id);
@PostExchange
Post createPost(@RequestBody Post post);
} @Configuration
public class HttpClientConfig {
@Bean
PostClient postClient(RestClient.Builder builder) {
RestClient restClient = builder.baseUrl("https://jsonplaceholder.typicode.com").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(PostClient.class);
}
}Enable Virtual Threads (Spring Boot 3.2+, JDK 21)
spring:
threads:
virtual:
enabled: trueJakarta Namespace Migration
// Spring Boot 2 style
import javax.servlet.http.HttpServletRequest;
import javax.persistence.Entity;
import javax.validation.constraints.NotBlank;
// Spring Boot 3 style
import jakarta.servlet.http.HttpServletRequest;
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotBlank;Migration Path from JDK 8 to Spring Boot 3
The Spring Boot Migrator tool can automatically scan a project and suggest migration actions. For manual migration, follow these stable steps:
Upgrade to Spring Boot 2.7 with JDK 17 first; verify the application runs before moving to 3.x.
Rename every javax package to jakarta using an IDE‑wide search/replace.
Check third‑party dependencies; any library still using javax must be upgraded to a Jakarta‑compatible version or replaced.
Increase test coverage, especially for Security, JPA, and Validation modules, and run full integration tests after changes.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
java1234
Former senior programmer at a Fortune Global 500 company, dedicated to sharing Java expertise. Visit Feng's site: Java Knowledge Sharing, www.java1234.com
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
