How to Seamlessly Upgrade Spring Boot 2.x to 3.x: Step‑by‑Step Guide

This guide explains why upgrading from Spring Boot 2.x to 3.x is essential, outlines the required JDK 17 migration, Spring Boot version bump, configuration property changes, Jakarta EE transition, and updates to Spring Security, Kafka, RestTemplate, and OpenAPI integration, providing 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, and Spring Boot is a tool that speeds up developing web applications and microservices with Spring.

Spring Boot 3.2.x has been released, bringing new features, bug fixes, and enhancements; support for Spring Boot 2.7.x ended on 2023‑11‑18, making migration to the 3.x line mandatory.

This article discusses how to migrate from Spring Boot 2.x to 3.x, the benefits of upgrading, and potential challenges developers may encounter.

Upgrade Guide

1. Upgrade JDK to 17

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

2. Upgrade to Spring Boot 3

After reviewing the status of your project and its dependencies, upgrade to the latest maintenance release of Spring Boot 3.0, e.g., 3.2.0.

Open pom.xml and update the Spring Boot version as follows:

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

3. Configuration Property Migration

In Spring Boot 3.0 some configuration properties have been renamed or removed; update your application.properties or application.yml accordingly. The spring-boot-properties-migrator module can help. Add the following dependency to pom.xml:

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

4. Upgrade to Jakarta EE

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

javax.persistence.*   -> jakarta.persistence.*
javax.validation.*   -> jakarta.validation.*
javax.servlet.*      -> jakarta.servlet.*
javax.annotation.*   -> jakarta.annotation.*
javax.transaction.*  -> jakarta.transaction.*

5. Adjust @ConstructorBinding Annotation

The @ConstructorBinding annotation is no longer required at the class level of @ConfigurationProperties; remove it. It can still be placed on a constructor when a class has multiple constructors to indicate which one should be used for property binding.

6. Spring MVC and WebFlux URL Matching Changes

Starting with Spring Framework 6.0, the trailing‑slash matching option is deprecated and defaults to false. Controllers that previously matched both GET /health and GET /health/ now behave differently. Example:

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

@RestController
public class HealthController {
    @GetMapping("/health")
    public Mono<String> health() {
        return Mono.just("Application is Working");
    }
}

7. RestTemplate Apache HttpClient Changes

Support for Apache HttpClient was removed in Spring Framework 6.0 and replaced by org.apache.httpcomponents.client5:httpclient5. If you encounter HTTP client issues, RestTemplate may fall back to the JDK client. Example RestTemplate configuration:

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

8. Spring Security Upgrade

Spring Boot 3.0 upgrades to Spring Security 6.0; WebSecurityConfigurerAdapter is deprecated. Use component‑based security configuration with the lambda DSL or define a SecurityFilterChain bean. Example using the deprecated adapter:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated())
            .httpBasic(withDefaults());
    }
}

Recommended modern approach:

@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. Updated send method example:

private RoutingKafkaTemplate routingKafkaTemplate;

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

10. Springdoc OpenAPI Upgrade

Use springdoc-openapi version 2 for Spring Boot 3 support. Add the appropriate starter dependency for WebMVC or WebFlux projects in pom.xml:

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

<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.

KafkaSpring BootOpenAPIspring-securityjava-17jakarta-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.