Backend Development 8 min read

Exploring Spring Boot 3.2 with Java 21, GraalVM Native Images, and Virtual Threads

This article demonstrates how Spring Boot 3.2 fully supports Java 21, Project Loom virtual threads, and GraalVM native images, providing step‑by‑step instructions, configuration details, and runnable code examples that showcase building, running, and profiling a Spring Boot application with these modern technologies.

Architecture Digest
Architecture Digest
Architecture Digest
Exploring Spring Boot 3.2 with Java 21, GraalVM Native Images, and Virtual Threads

Spring Boot 3.2 was recently released and brings first‑class support for Java 21, Project Loom virtual threads, and GraalVM native images, allowing developers to build high‑performance, low‑overhead Java applications.

Java 21

The new release fully supports Java 21, which introduces 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 that enables lightweight, high‑concurrency execution. The official JEP 444 provides a detailed explanation.

https://openjdk.org/jeps/444

GraalVM and Native Images

GraalVM is a high‑performance JDK that uses 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, resulting in faster startup and lower runtime memory usage compared with a traditional JVM.

Native Image produces an executable that contains application classes, dependencies, runtime libraries, and statically linked native code from the JDK.

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 the official site.

https://www.graalvm.org/downloads/

Create a new Spring Boot project with Spring Initializr, selecting Spring Boot 3.2.0, Java 21, Gradle‑Groovy, Spring Web, and GraalVM native support.

Enable virtual threads by adding the following property to application.yml or application.properties :

spring.threads.virtual.enabled: true

This configuration makes Tomcat handle HTTP requests on virtual threads, allows @Async methods and Spring WebFlux blocking execution to use virtual threads, and runs @Scheduled methods on virtual threads.

Code Examples

1. Simple Tomcat controller

@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 with ./gradlew bootRun , then call the endpoint:

curl -X GET 'localhost:8085/test'

The console output shows that the controller, async, and scheduled methods are executed on virtual threads belonging to a shared ForkJoinPool, confirming the expected FIFO work‑stealing scheduling behavior described in JEP 444.

The virtual thread scheduler is a work‑stealing ForkJoinPool that runs in FIFO mode, with parallelism equal to the number of platform threads available for scheduling virtual threads.

Building a Native Image

Compile a GraalVM native image (this may take several minutes) and run it:

./gradlew nativeCompile
./build/native/nativeCompile/app

The native executable starts much faster and uses less memory, matching the claims about native images.

Conclusion

Spring Boot 3.2 combined with virtual threads and GraalVM native images enables developers to write code that approaches Go‑level performance while retaining 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.

Backend DevelopmentSpring BootVirtual ThreadsGraalVMnative-imageJava 21
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.