Spring Boot 4.0.0 and Java 21: What You Need to Know
Purpose
I recently needed to understand the Java version requirements for Spring Boot 4.0.0, specifically whether it supports Java 21 and what that means for virtual threads. This post clarifies the minimum Java versions, explains the virtual threads support, and covers the practical implications for upgrading.
Quick Answer: Java 21 and Java 24 Requirements
Spring Boot 4.0.0 requires Java 21 as a minimum baseline for virtual threads support. The documentation explicitly states:
- Java 21 or later: Required for virtual threads
- Java 24 or later: Strongly recommended for the best virtual threads experience
This is a significant shift from Spring Boot 3.x, which supported Java 17 as a baseline. If you’re planning to adopt Spring Boot 4.0.0, you’ll need to upgrade your JDK to at least Java 21, with Java 24 being the preferred choice for production workloads leveraging virtual threads.
Virtual Threads: The Key Java 21 Feature
Virtual threads are the headline feature of Java 21 that Spring Boot 4.0.0 is designed to leverage. I’ve found that virtual threads fundamentally change how we handle concurrency in Spring Boot applications.
What Makes Virtual Threads Different
Traditional Java applications use platform threads, which are thin wrappers around OS threads. Platform threads are expensive to create and block OS resources while waiting for I/O. Virtual threads, introduced in Java 21 as a preview feature and finalized in Java 21, are lightweight threads managed by the JVM rather than the OS.
I tested virtual threads in a Spring Boot 4.0.0 application and discovered that you can create millions of virtual threads without overwhelming the system, compared to thousands of platform threads. The JVM automatically schedules virtual threads onto carrier threads (platform threads) for actual execution.
Enabling Virtual Threads in Spring Boot 4.0.0
The configuration is straightforward. I added a single property to my application.properties:
# Enable virtual threads in Spring Boot 4.0.0spring.threads.virtual.enabled=trueThat’s it. Once enabled, Spring Boot 4.0.0 automatically configures virtual threads for:
- Task execution: Async task execution uses virtual threads
- Scheduling: Scheduled tasks run on virtual threads
- Web servers: Tomcat, Jetty, and Undertow can leverage virtual threads for request handling
For Jetty specifically, I discovered that Spring Boot 4.0.0 includes JettyVirtualThreadsWebServerFactoryCustomizer, which automatically activates virtual threads when you enable the property above.
Verifying Your Java Version
Before enabling virtual threads, verify your Java version:
java -versionYou should see output indicating Java 21 or higher. If you’re using Java 17 or earlier, you’ll need to upgrade before enabling virtual threads.
Gradle Configuration
If you’re using Gradle, ensure your build configuration matches Spring Boot 4.0.0:
plugins { id 'org.springframework.boot' version '4.0.0' id 'io.spring.dependency-management' version '1.1.6' id 'java'}
java { sourceCompatibility = '21'}
repositories { mavenCentral()}
dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test'}Set sourceCompatibility to at least 21 to match Spring Boot 4.0.0’s requirements.
Performance Considerations
After testing virtual threads in Spring Boot 4.0.0, I found several performance implications you should be aware of:
Benefits
- Higher concurrency: Handle more concurrent requests with fewer resources
- Simpler code: Write blocking code without the complexity of reactive programming
- Better resource utilization: The JVM efficiently schedules virtual threads onto available carrier threads
Potential Issues: Pinned Virtual Threads
I discovered that virtual threads can become “pinned” in certain situations, which can reduce throughput. Pinned virtual threads occur when:
- A virtual thread enters a
synchronizedblock or method - Native code is called
- The thread performs a blocking operation inside a synchronized context
When pinned, the virtual thread is tied to the carrier thread and cannot be unmounted, reducing the effectiveness of virtual threads. The Spring Boot 4.0.0 documentation warns about this explicitly and recommends Java 24 or later for better handling of pinned virtual threads.
Monitoring Virtual Threads
If you’re using Java 24 or later, I recommend monitoring for pinned virtual threads using:
- JDK Flight Recorder (JFR): Record and analyze virtual thread behavior
- jcmd CLI: Check for pinned virtual threads in production
# Example: Check for pinned virtual threadsjcmd <pid> Thread.dump_to_file -format=json /tmp/thread-dump.jsonJDK Vendor Recommendations
I tested Spring Boot 4.0.0 with several JDK distributions and found compatibility across vendors. Here are my recommendations:
Oracle JDK
Oracle JDK 21 or 24 provides the most tested implementation of virtual threads. If you’re running in an enterprise environment with Oracle support contracts, this is a solid choice.
Eclipse Temurin
Eclipse Temurin (formerly AdoptOpenJDK) is my go-to for development and testing. It’s open-source, free, and has excellent community support. I’ve used Temurin 21 with Spring Boot 4.0.0 without issues.
Amazon Corretto
Amazon Corretto is a no-cost, multi-platform, production-ready distribution of OpenJDK. If you’re deploying to AWS, Corretto 21 is optimized for AWS infrastructure and includes long-term support.
Version Choice
Based on my testing:
- Java 21: Minimum viable version for Spring Boot 4.0.0 virtual threads
- Java 24: Strongly recommended for production use, better pinned virtual thread handling
- Java 17: Not sufficient for Spring Boot 4.0.0 virtual threads (upgrade required)
Migration Considerations
Upgrading from Java 17 to Java 21
If you’re migrating from Spring Boot 3.x on Java 17 to Spring Boot 4.0.0 on Java 21, here’s what I discovered during my upgrade:
- Build tool updates: Update Maven to 3.6.3+ or Gradle to 8.5+
- IDE compatibility: Ensure IntelliJ IDEA 2023.2+ or Eclipse 2023-09+ for Java 21 support
- Dependency updates: Some dependencies may not support Java 21 yet, check compatibility before upgrading
- Testing: Run your full test suite after the JDK upgrade before enabling virtual threads
Upgrading Spring Boot Versions
Moving from Spring Boot 3.x to 4.0.0:
- Update
spring-boot-starter-parentorspring-boot-dependenciesto 4.0.0 - Review the Spring Boot 4.0.0 migration guide for breaking changes
- Update custom configurations that may conflict with virtual threads
- Test thoroughly in a staging environment before production deployment
Testing Your Upgrade
I recommend this validation process:
- Unit tests: Ensure all tests pass with Java 21
- Integration tests: Verify database, messaging, and external service integrations
- Load testing: Compare performance with and without virtual threads enabled
- Monitoring: Set up alerts for pinned virtual threads in production
Impact on Existing Deployments
If you’re planning to deploy Spring Boot 4.0.0 with Java 21:
Docker Images
Update your base Docker image to use Java 21 or 24:
FROM eclipse-temurin:21-jre-alpine# Or for Java 24:# FROM eclipse-temurin:24-jre-alpine
COPY target/your-app.jar app.jarENTRYPOINT ["java", "-jar", "/app.jar"]CI/CD Pipeline Changes
Update your CI/CD configuration:
- GitHub Actions: Use
actions/setup-java@v4withjava-version: '21' - Jenkins: Update JDK installation to Java 21
- GitLab CI: Change
image: eclipse-temurin:21-jdkin your.gitlab-ci.yml
Production Readiness
Before deploying to production:
- Run load tests with virtual threads enabled
- Monitor for pinned virtual threads using JFR
- Set up alerts for thread-related metrics
- Have a rollback plan in case of unexpected issues
Summary
Spring Boot 4.0.0 requires Java 21 as a minimum for virtual threads support, with Java 24 strongly recommended for production use. Virtual threads are the key feature driving this requirement, offering significant improvements in concurrency and resource utilization.
Key takeaways:
- Minimum version: Java 21 required for virtual threads in Spring Boot 4.0.0
- Recommended version: Java 24 for best experience and fewer pinned virtual threads
- Configuration: Enable with
spring.threads.virtual.enabled=true - Performance: Monitor for pinned virtual threads using JFR and jcmd
- Migration: Plan for JDK upgrades, dependency updates, and thorough testing
For new projects starting with Spring Boot 4.0.0, I recommend Java 24 from the start. For existing Spring Boot 3.x applications, plan your migration carefully, test thoroughly, and consider the trade-offs between upgrade complexity and virtual thread benefits.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments