Why Upgrade to JDK 21 and Spring Boot 2.7.18? Boost Performance and Future‑Proof Your Apps

Upgrading a company's Java stack from JDK 11 to JDK 21, while staying on Spring Boot 2.7.18, provides long‑term security support, leverages virtual threads, new low‑latency garbage collectors, modern language features like records and pattern‑matching, and avoids costly Jakarta EE namespace migration, with detailed steps for pom changes, MongoDB configuration, code adjustments, and post‑upgrade validation.

WeiLi Technology Team
WeiLi Technology Team
WeiLi Technology Team
Why Upgrade to JDK 21 and Spring Boot 2.7.18? Boost Performance and Future‑Proof Your Apps

Background

The company plans to upgrade its Java technology stack from JDK 11 to JDK 21. JDK 11 is the previous LTS version, but ten newer releases have introduced many revolutionary features and low‑level optimizations. JDK 21, as the latest LTS, consolidates these innovations.

Why the Upgrade Is Necessary

End of free public updates for JDK 11 : Oracle stopped public updates in September 2023, so without commercial support the production environment would miss critical security patches.

Framework and library requirements : Major frameworks such as Spring Framework 6 and Spring Boot 3.x already require at least JDK 17, making JDK 21 a prerequisite for using their latest features.

Key JDK 21 Features

Virtual Threads

Virtual threads (Project Loom) are the flagship feature of JDK 21. They replace heavyweight platform threads with lightweight virtual threads, allowing developers to write high‑concurrency code in a synchronous, sequential style. A single JVM can create millions of virtual threads, dramatically increasing I/O‑bound throughput while reducing code complexity.

Next‑Generation Garbage Collectors

ZG C and Shenandoah : Both low‑latency collectors are production‑ready in JDK 21, offering sub‑millisecond pause times for latency‑sensitive applications.

G1 GC improvements : As the default collector, G1 receives numerous optimizations, delivering better throughput and latency than in JDK 11.

Language Enhancements

Records (JDK 16) : One‑line immutable data carriers. Example: public record Point(int x, int y) { } Pattern Matching for Switch (JDK 21) : Safer, more expressive switch statements. Example:

Object obj = ...;
switch (obj) {
  case String s -> System.out.println("String: " + s.toUpperCase());
  case Integer i -> System.out.println("Integer: " + i);
  default -> {}
}

Text Blocks (JDK 15) : Multi‑line string literals without concatenation. Example:

String json = """
  {
    "name": "John",
    "age": 30
  }
""";

Other Important Features

Record patterns for elegant deconstruction.

Sealed classes (JDK 17) for stricter inheritance control.

Improved var type inference.

More informative NullPointerExceptions.

Spring Boot Version Compatibility

Spring Boot versions map to supported JDK ranges:

2.1 – 2.4: JDK 8‑16

2.5 – 2.6: JDK 8‑19

2.7: JDK 8‑21

3.0 – 3.2: JDK 17‑23

Choosing Spring Boot 2.7.18 allows the project to stay on JDK 8‑21, avoiding the disruptive migration to Jakarta EE that Spring Boot 3.x requires.

Namespace Migration Challenges

Moving from Java EE (javax.*) to Jakarta EE (jakarta.*) entails:

Global code changes: updating import statements across hundreds of files.

Dependency ecosystem overhaul: all third‑party libraries (database drivers, messaging queues, caches, security frameworks, custom starters) must provide Jakarta‑compatible versions.

Transitive dependency conflicts: lingering javax packages can cause ClassNotFoundException or NoClassDefFoundError.

Potential hidden bugs in libraries that claim Jakarta compatibility but fail in edge cases.

Decision Conclusion

Adopting Spring Boot 2.7.18 together with JDK 21 avoids the high‑risk, high‑cost Jakarta EE migration while still gaining the performance, security, and productivity benefits of the new JDK.

Upgrade Steps

Tool Preparation

Upgrade IntelliJ IDEA to version 2025.2.

Use Maven 3.6.1.

Deploy on Tomcat 8 or 9.

Step 1 – Modify pom.xml

Update the parent version to the JDK‑21 snapshot:

<parent>
  <groupId>suishen-webx</groupId>
  <artifactId>suishen-webx-parent</artifactId>
  <version>3.0-jdk21-SNAPSHOT</version>
</parent>

Step 2 – Update MongoDB Configuration

Replace the old mongo:mongo-client configuration with a ConnectionString and the new Spring Data MongoDB factory:

<!-- Build connection string with URL‑encoded credentials -->
<bean id="mongoConnectionString" class="com.mongodb.ConnectionString">
  <constructor-arg value="#{'mongodb://' + T(java.net.URLEncoder).encode('${mongo.username}', 'UTF-8') + ':' + T(java.net.URLEncoder).encode('${mongo.password}', 'UTF-8') + '@${mongo.hostport}/${mongo.dbname}?authSource=${mongo.dbname}&maxPoolSize=${mongo.connectionsPerHost:500}&connectTimeoutMS=${mongo.connectTimeout:5000}&socketTimeoutMS=${mongo.socketTimeout:10000}&serverSelectionTimeoutMS=${mongo.maxWaitTime:5000}'}"/>
</bean>

<!-- Create MongoClient -->
<bean id="mongoClient" class="com.mongodb.client.MongoClients" factory-method="create">
  <constructor-arg ref="mongoConnectionString"/>
</bean>

<!-- Create MongoDatabaseFactory -->
<bean id="mongoDbFactory" class="org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory">
  <constructor-arg ref="mongoClient"/>
  <constructor-arg value="${mongo.dbname}"/>
</bean>

Step 3 – Adjust Code

Replace deprecated sort construction:

new Sort(Sort.Direction.DESC, "startTime") → Sort.by(Sort.Direction.DESC, "startTime")

Update Redis ZParams usage:

ZParams zParams = new ZParams().aggregate(ZParams.Aggregate.SUM).weightsByDouble(weightsDouble) → ZParams zParams = new ZParams().aggregate(ZParams.Aggregate.SUM).weights(weightsDouble)

Step 4 – CI/CD Pipeline

Change the build environment to tomcat9_jdk21 and adjust pipeline scripts accordingly.

Step 5 – Post‑Upgrade Verification

Check application startup logs for class‑loading errors or dependency conflicts.

Monitor CPU, memory, and GC logs to ensure ZGC/G1 operate correctly.

Run full regression tests to confirm business functionality.

Watch for JDK‑specific exceptions in error logs.

Validate connectivity to external services (databases, Redis, message queues, etc.).

Summary of Benefits

Long‑term support : JDK 21 will receive security updates for at least eight years.

Performance gains : Virtual threads and modern GC dramatically improve concurrency and latency.

Code quality : Records, pattern matching, and other language features reduce boilerplate and increase safety.

Technical competitiveness : The upgrade prepares the codebase for future adoption of Spring Boot 3.x and other modern stacks.

Although the migration requires careful dependency version alignment and some code refactoring, selecting Spring Boot 2.7.18 avoids the costly Jakarta EE namespace shift while still unlocking JDK 21’s core advantages, resulting in a smooth and controlled upgrade path.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavamigrationperformanceJDK21VirtualThreads
WeiLi Technology Team
Written by

WeiLi Technology Team

Practicing data-driven principles and believing technology can change the world.

0 followers
Reader feedback

How this landed with the community

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.