Skip to content

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.0
spring.threads.virtual.enabled=true

That’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:

Terminal window
java -version

You 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 synchronized block 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
Terminal window
# Example: Check for pinned virtual threads
jcmd <pid> Thread.dump_to_file -format=json /tmp/thread-dump.json

JDK 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:

  1. Build tool updates: Update Maven to 3.6.3+ or Gradle to 8.5+
  2. IDE compatibility: Ensure IntelliJ IDEA 2023.2+ or Eclipse 2023-09+ for Java 21 support
  3. Dependency updates: Some dependencies may not support Java 21 yet, check compatibility before upgrading
  4. 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:

  1. Update spring-boot-starter-parent or spring-boot-dependencies to 4.0.0
  2. Review the Spring Boot 4.0.0 migration guide for breaking changes
  3. Update custom configurations that may conflict with virtual threads
  4. Test thoroughly in a staging environment before production deployment

Testing Your Upgrade

I recommend this validation process:

  1. Unit tests: Ensure all tests pass with Java 21
  2. Integration tests: Verify database, messaging, and external service integrations
  3. Load testing: Compare performance with and without virtual threads enabled
  4. 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.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

CI/CD Pipeline Changes

Update your CI/CD configuration:

  • GitHub Actions: Use actions/setup-java@v4 with java-version: '21'
  • Jenkins: Update JDK installation to Java 21
  • GitLab CI: Change image: eclipse-temurin:21-jdk in your .gitlab-ci.yml

Production Readiness

Before deploying to production:

  1. Run load tests with virtual threads enabled
  2. Monitor for pinned virtual threads using JFR
  3. Set up alerts for thread-related metrics
  4. 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