How to Seamlessly Upgrade Spring Boot 2.x to 3.x – Step-by-Step Guide

This guide walks developers through upgrading from Spring Boot 2.x to 3.x, covering JDK 17 migration, pom.xml changes, configuration property updates, Jakarta EE transition, security reconfiguration, Kafka template adjustments, and OpenAPI integration, with code examples for each step.

Programmer DD
Programmer DD
Programmer DD
How to Seamlessly Upgrade Spring Boot 2.x to 3.x – Step-by-Step Guide

Spring Framework is a popular open‑source enterprise framework for building standalone production‑grade applications on the JVM. Spring Boot speeds up development of web applications and microservices.

Spring Boot 3.2.x has been released, bringing new features, bug fixes and enhancements. Support for Spring Boot 2.7.x ended on 18 Nov 2023, making migration to 3.x mandatory.

Upgrade Guide

1. Upgrade to JDK 17

Spring Boot 3.0 requires Java 17 as the minimum version. If you are on Java 8 or 11, upgrade the JDK before migrating.

2. Upgrade to Spring Boot 3

After checking your project and dependencies, upgrade to the latest maintenance release of Spring Boot 3.0 (example uses 3.2.0). Update the pom.xml parent version:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
</parent>

3. Migrate Configuration Properties

Some properties were renamed or removed in Spring Boot 3.0. Update application.properties or application.yml accordingly. Add the spring-boot-properties-migrator module to your pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>

4. Switch to Jakarta EE

All Java EE APIs have moved to Jakarta EE. Replace javax imports with jakarta equivalents, e.g.:

javax.persistence.*   → jakarta.persistence.*
javax.validation.*   → jakarta.validation.*
javax.servlet.*       → jakarta.servlet.*
javax.annotation.*   → jakarta.annotation.*
javax.transaction.*   → jakarta.transaction.*

5. Adjust @ConstructorBinding

The @ConstructorBinding annotation is no longer required on @ConfigurationProperties classes; remove it. It can still be placed on a constructor when multiple constructors exist.

6. URL‑matching changes in Spring MVC and WebFlux

Trailing‑slash matching is deprecated and defaults to false. Controllers that previously matched both GET /health and GET /health/ need to be updated.

@RestController
public class HealthController {
    @GetMapping("/health")
    public String health() {
        return "Application is Working";
    }
}

7. Apache HttpClient removal

Spring Framework 6.0 dropped support for Apache HttpClient. Use org.apache.httpcomponents.client5:httpclient5 instead, or fall back to the JDK client. Example RestTemplate configuration:

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        SSLConnectionSocketFactory sslFactory = SSLConnectionSocketFactoryBuilder.create().build();
        PoolingHttpClientConnectionManager manager = PoolingHttpClientConnectionManagerBuilder.create()
                .setSSLSocketFactory(sslFactory).build();
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(manager).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setHttpClient(httpClient);
        return new RestTemplate(factory);
    }
}

8. Spring Security upgrade

Spring Boot 3.0 upgrades to Spring Security 6.0; WebSecurityConfigurerAdapter is deprecated. Use component‑based configuration with the SecurityFilterChain bean:

@Configuration
public class SecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated())
            .httpBasic(withDefaults());
        return http.build();
    }
}

9. Spring Kafka template upgrade

The KafkaTemplate now returns CompletableFuture instead of the deprecated ListenableFuture. Update send logic accordingly.

private RoutingKafkaTemplate routingKafkaTemplate;

public void send() {
    CompletableFuture<SendResult<Object, Object>> future =
        routingKafkaTemplate.send("Message", "topic");
    future.thenAccept(log::info)
          .exceptionally(e -> { log.error(e); return null; });
}

10. Springdoc OpenAPI upgrade

Use springdoc‑openapi v2 for Spring Boot 3 support. Add the appropriate starter dependency for WebMVC or WebFlux projects:

<!-- WebMVC -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>

<!-- WebFlux -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
    <version>2.3.0</version>
</dependency>
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.

JavaKafkaSpring Bootspring-securityjakarta-ee
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.