Exploring Spring Boot 3.2 with Java 21, Virtual Threads, and GraalVM Native Images
This article demonstrates how to use Spring Boot 3.2 together with Java 21, Project Loom virtual threads, and GraalVM native images, providing step‑by‑step setup, configuration, and code examples for controllers, async tasks, scheduled jobs, and native compilation.
Spring Boot 3.2 was released yesterday, bringing full support for Java 21, virtual threads (Project Loom), and GraalVM native images.
Java 21
Java 21, released on 19 September 2023, offers thousands of performance, stability, and security improvements that help developers increase productivity and drive innovation.
Virtual Threads
One of the most important updates is virtual threads, a feature of Project Loom. The official JEP (https://openjdk.org/jeps/444) provides a detailed explanation.
GraalVM and Native Images
GraalVM is a high‑performance JDK that can use an alternative JIT compiler to accelerate Java and JVM‑based applications. Its Native Image technology compiles Java code ahead‑of‑time into a standalone executable that includes application classes, dependencies, runtime libraries, and statically linked native code, resulting in faster startup and lower runtime memory usage compared with the JVM.
Getting Started
Install Java 21.0.1‑graal via SDKMAN:
sdk install java 21.0.1-graal
sdk default java 21.0.1-graal
Alternatively, download GraalVM manually from https://www.graalvm.org/downloads/.
Create a new Spring Boot project with Spring Initializr using Spring Boot 3.2.0, Java 21, Gradle‑Groovy, Spring Web, and GraalVM native support dependencies.
Enable virtual threads by adding the following property to application.yml or application.properties :
spring.threads.virtual.enabled: trueThis makes Tomcat handle HTTP requests on virtual threads, enables @Async and Spring WebFlux blocking execution to use virtual threads, and runs @Scheduled methods on virtual threads.
Code Examples
1. Simple controller for Tomcat HTTP requests
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger log = LoggerFactory.getLogger(TestController.class);
@GetMapping
public void test() {
log.info("Rest controller method has been called {}", Thread.currentThread());
}
}2. Asynchronous task
@Component
public class AsyncTaskExecutorService {
private static final Logger log = LoggerFactory.getLogger(AsyncTaskExecutorService.class);
@Async
public void run() {
log.info("Async task method has been called {}", Thread.currentThread());
}
}3. Scheduled task (every 15 seconds)
@Component
public class SchedulerService {
private static final Logger log = LoggerFactory.getLogger(SchedulerService.class);
@Scheduled(fixedDelayString = "15000")
public void run() {
log.info("Scheduled method has been called {}", Thread.currentThread());
}
}Run the application:
./gradlew bootRunCall the endpoint:
curl -X GET 'localhost:8085/test'The logs show that the controller, async, and scheduled methods are executed on virtual threads belonging to the common ForkJoinPool.
According to JEP 444, the virtual‑thread scheduler is a work‑stealing ForkJoinPool that runs in FIFO order, with parallelism equal to the number of platform threads available for scheduling virtual threads.
Building a GraalVM Native Image
Compile the native image (this may take several minutes) and run it:
./gradlew nativeCompile
./build/native/nativeComplie/appThe native executable starts much faster and uses less runtime memory, confirming the advantages of GraalVM native images over the traditional JVM.
The full source code used in this article is available at https://github.com/egor-ponomarev/spring-boot3.2-with-graalvm-virtual-threads-example.
Conclusion
Spring Boot 3.2 brings the long‑awaited support for virtual threads and GraalVM native images, allowing developers to write code with Go‑like performance and scalability while staying within the rich JVM ecosystem. However, not all libraries are yet compatible with virtual threads, so developers should verify library behavior before adopting them in production.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.