COBRA-Libs Upgrade Guide: Migrating to JDK 21 & Spring Boot 3.5.6
Description
All COBRA shared libraries have been upgraded from JDK <= 8 / JDK 11 -> JDK 21 and Spring Boot 2.x -> Spring Boot 3.5.6. These libraries are published to JFrog Artifactory and consumed by 10+ teams across the organization.
This document walks your team through every step required to adopt the new library versions in your application.
These COBRA library versions are designed for use with the Spring Boot application stack. Teams must be on pipeline v4.7 or higher to support JDK 21 - upgrading to pipeline v4.8 is recommended for the latest improvements and full compatibility.
Before you upgrade a production environment, use the procedures in this document to upgrade a non-production environment that reproduces your production environment, to test that your application is compatible with the new versions.
IMPORTANT:
Follow the steps in order. Skipping steps may result in hard-to-debug compilation or runtime errors.
What Has Changed
COBRA Library Version Reference
Library (artifactId) | Group ID | Old Version | New Version | Spring Boot | JDK |
|---|---|---|---|---|---|
commons-lib | com.netapp.cobra | 3.x.x | 4.0.6 | 3.5.6 | 21 |
cobra-commons-auth-server | com.netapp.cobra | 1.x.x | 2.0.4 | 3.5.6 | 21 |
cobra-commons-user | com.netapp.cobra | 2.x.x | 3.0.4 | 3.5.6 | 21 |
commons-mongodb | com.netapp.cobra | 1.x.x | 2.0.0 | 3.5.6 | 21 |
cobra-commons-cis-consumer | com.netapp.cobra | 1.x.x | 2.0.0 | 3.5.6 | 21 |
cobra-commons-cis-producer | com.netapp.cobra | 1.x.x | 2.0.1 | 3.5.6 | 21 |
cobra-sc-commons-gateway | com.netapp.cobra | 1.x.x | 2.0.6 | 3.5.6 | 21 |
commons-logger | com.netapp.cobra | 1.x.x | 2.0.0 | 3.5.6 | 21 |
commons-preference | com.netapp.cobra | 1.x.x | 2.0.0 | 3.5.6 | 21 |
Platform Version Reference
| Component | Old Version | New Version |
|---|---|---|
| Java / JDK | 8 / 11 | 21 |
| Spring Boot | 2.x.x | 3.5.6 |
| Spring Cloud | Hoxton.SR4 / 2021.0.4 | 2025.0.0 |
| Jakarta EE | javax.* (EE 8) | jakarta.* (EE 10) |
Summary of Breaking Changes
| Change | Old | New |
|---|---|---|
| Namespace | javax.* | jakarta.* |
| Distributed Tracing | Spring Cloud Sleuth | Micrometer Tracing |
| Circuit Breaker | Netflix Hystrix | Resilience4j |
| API Gateway | Netflix Zuul | Spring Cloud Gateway |
| OAuth2 Auto-configure | spring-security-oauth2-autoconfigure | Native Spring Security 6 OAuth2 |
| Embedded MongoDB (tests) | de.flapdoodle.embed.mongo | de.flapdoodle.embed.mongo.spring30x |
| Thymeleaf Java 8 Time extras | thymeleaf-extras-java8time | Built-in (removed dependency) |
Prerequisites
Before you begin, ensure your local and CI/CD environments meet the following requirements.
Local Development
- JDK 21 installed. Download: Eclipse Temurin 21 or organization's approved distribution.
- Maven 3.8.6+ (Maven 3.9.x recommended)
mvn --version
# Should show Apache Maven 3.8.x or higher, Java version: 21 - IDE updated to support JDK 21 (IntelliJ IDEA 2023.1+, Eclipse 2023-06+, VS Code with Java Extension Pack)
- Access to JFrog Artifactory (
https://artifactory.devops.netapp.com)
CI/CD Pipeline
- Pipeline agent / Docker image uses JDK 21
-
JAVA_HOMEenvironment variable points to JDK 21 - Maven settings (
~/.m2/settings.xml) configured with Artifactory credentials
Artifactory Settings
Ensure your ~/.m2/settings.xml (or pipeline equivalent) includes:
<settings>
<servers>
<server>
<id>central</id>
<username>${ARTIFACTORY_USER}</username>
<password>${ARTIFACTORY_PASSWORD}</password>
</server>
<server>
<id>snapshots</id>
<username>${ARTIFACTORY_USER}</username>
<password>${ARTIFACTORY_PASSWORD}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>artifactory-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://artifactory.devops.netapp.com/artifactory/maven-ngdc</url>
</mirror>
</mirrors>
</settings>
Upgrade Procedure
Step 1 - Upgrade to JDK 21
1.1 Update pom.xml Java Version
In your application's pom.xml, change the java.version property:
<!-- Before -->
<properties>
<java.version>8</java.version>
<!-- or: <java.version>11</java.version> -->
</properties>
<!-- After -->
<properties>
<java.version>21</java.version>
</properties>
1.2 Update Maven Compiler Plugin
Ensure the compiler plugin uses <release> (not <source>/<target>):
<!-- Before (older style) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!-- After (recommended for JDK 9+) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
1.3 IDE - Configure Project SDK
- IntelliJ IDEA:
File -> Project Structure -> Project -> SDK -> Select JDK 21 - Eclipse:
Project -> Properties -> Java Build Path -> Libraries -> JRE System Library -> JDK 21 - VS Code: Update
.vscode/settings.json:{
"java.configuration.runtimes": [
{
"name": "JavaSE-21",
"path": "/path/to/jdk-21",
"default": true
}
]
}
Step 2 - Update Spring Boot Parent
Update the Spring Boot parent version in your pom.xml:
<!-- Before -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<!-- After -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version>
<relativePath/>
</parent>
Note: Use 3.5.6 - all COBRA libraries on the dev branch are built against this version.
Step 3 - Update Spring Cloud BOM
Update the Spring Cloud BOM version in your dependencyManagement section:
<!-- Before -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version> <!-- or 2021.0.4 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- After -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2025.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Step 4 - Update COBRA Library Versions
Update the version of each COBRA library your application uses. Refer to the table in the What Has Changed section for exact new versions.
4.1 Add/Update Version Properties
<properties>
<!-- Core commons library (used by almost all COBRA services) -->
<cobra.commons.version>4.0.6</cobra.commons.version>
<!-- Auth server library (if your service uses COBRA auth) -->
<cobra.commons-authserver.version>2.0.4</cobra.commons-authserver.version>
<!-- User gateway library (if applicable) -->
<cobra.commons-user.version>3.0.4</cobra.commons-user.version>
<!-- MongoDB commons library (if applicable) -->
<cobra.commons-mongodb.version>2.0.0</cobra.commons-mongodb.version>
<!-- CIS consumer library (if applicable) -->
<cobra.commons-cis-consumer.version>2.0.0</cobra.commons-cis-consumer.version>
<!-- CIS producer library (if applicable) -->
<cobra.commons-cis-producer.version>2.0.1</cobra.commons-cis-producer.version>
<!-- Spring Cloud Gateway commons library (if applicable) -->
<cobra.sc-gateway.version>2.0.6</cobra.sc-gateway.version>
<!-- Logger library (if applicable) -->
<cobra.commons-logger.version>2.0.0</cobra.commons-logger.version>
<!-- Preference library (if applicable) -->
<cobra.commons-preference.version>2.0.0</cobra.commons-preference.version>
</properties>
4.2 Update Dependency Declarations
<dependencies>
<!-- Core commons (almost every service uses this) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>commons-lib</artifactId>
<version>${cobra.commons.version}</version>
</dependency>
<!-- Auth server (if your service handles authentication) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-commons-auth-server</artifactId>
<version>${cobra.commons-authserver.version}</version>
</dependency>
<!-- User gateway (if your service manages users) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-commons-user</artifactId>
<version>${cobra.commons-user.version}</version>
</dependency>
<!-- MongoDB commons (if your service uses MongoDB shared logic) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>commons-mongodb</artifactId>
<version>${cobra.commons-mongodb.version}</version>
</dependency>
<!-- CIS consumer (if your service consumes Kafka/CIS events) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-commons-cis-consumer</artifactId>
<version>${cobra.commons-cis-consumer.version}</version>
</dependency>
<!-- CIS producer (if your service produces Kafka/CIS events) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-commons-cis-producer</artifactId>
<version>${cobra.commons-cis-producer.version}</version>
</dependency>
<!-- Spring Cloud Gateway commons (if your service is an SC Gateway) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-sc-commons-gateway</artifactId>
<version>${cobra.sc-gateway.version}</version>
</dependency>
<!-- Logger commons (if your service uses the COBRA logging library) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>commons-logger</artifactId>
<version>${cobra.commons-logger.version}</version>
</dependency>
<!-- Preference commons (if your service uses the COBRA preference library) -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>commons-preference</artifactId>
<version>${cobra.commons-preference.version}</version>
</dependency>
</dependencies>
Note: Only add the dependencies your service actually uses. Do not blindly add all of them.
Step 5 - Replace Removed or Deprecated Dependencies
Spring Boot 3.x removed several legacy dependencies. Follow each sub-section that applies to your service.
5.1 Remove spring-security-oauth2-autoconfigure
This artifact is not compatible with Spring Boot 3 and must be removed entirely.
<!-- REMOVE THIS (not compatible with Spring Boot 3) -->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<!-- REMOVE THIS legacy oauth2 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
Replace with native Spring Security 6 OAuth2 starters:
<!-- For resource servers (services that validate tokens) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<!-- For OAuth2 clients (services that call other services using OAuth2) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<!-- For authorization servers -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
5.2 Replace Spring Cloud Sleuth with Micrometer Tracing
Spring Cloud Sleuth has been retired. Replace it with Micrometer Tracing.
<!-- REMOVE THIS -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- ADD THIS instead -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
No code changes are typically needed - Micrometer Tracing is a drop-in replacement for Sleuth's MDC-based trace/span propagation.
5.3 Replace Netflix Hystrix with Resilience4j
Netflix Hystrix is end-of-life and removed from Spring Cloud 2020+.
<!-- REMOVE THESE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- ADD THIS instead (for servlet-based Spring MVC services) -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
<!-- OR THIS for reactive/WebFlux services -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
Note: Code change required - replace
@HystrixCommandannotations with@CircuitBreakerfrom Resilience4j. See the Resilience4j Migration Guide.
5.4 Replace Netflix Zuul with Spring Cloud Gateway
Netflix Zuul is removed from Spring Cloud.
<!-- REMOVE THIS -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- Use the COBRA Spring Cloud Gateway commons lib instead -->
<dependency>
<groupId>com.netapp.cobra</groupId>
<artifactId>cobra-sc-commons-gateway</artifactId>
<version>2.0.6</version>
</dependency>
<!-- Or use Spring Cloud Gateway directly -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
</dependency>
Note: Spring Cloud Gateway is reactive (WebFlux). If your service was Spring MVC (servlet-based), migration requires more effort. Consult the platform team.
5.5 Update Embedded MongoDB for Tests
<!-- REMOVE THIS (not compatible with Spring Boot 3) -->
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
<!-- ADD THIS instead (Spring Boot 3 compatible) -->
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo.spring30x</artifactId>
<version>4.14.0</version>
<scope>test</scope>
</dependency>
5.6 Remove thymeleaf-extras-java8time
Java 8 time support is built into Thymeleaf 3.1+ (included in Spring Boot 3). Remove this dependency:
<!-- REMOVE THIS (included in Thymeleaf 3.1+ automatically) -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
5.7 Replace commons-beanutils (if used)
commons-beanutils has known vulnerabilities. Replace with a maintained alternative or remove if no longer needed:
<!-- REMOVE OR REVIEW -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
If you must keep it, upgrade to the latest version and add an exclusion for commons-logging:
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.11.0</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Step 6 - Migrate javax to jakarta Imports
Spring Boot 3 is built on Jakarta EE 9+, which renamed all javax.* packages to jakarta.*. This is a mandatory code change.
Common Import Replacements
Old (javax) | New (jakarta) |
|---|---|
javax.servlet.http.HttpServletRequest | jakarta.servlet.http.HttpServletRequest |
javax.servlet.http.HttpServletResponse | jakarta.servlet.http.HttpServletResponse |
javax.servlet.Filter | jakarta.servlet.Filter |
javax.persistence.* | jakarta.persistence.* |
javax.validation.* | jakarta.validation.* |
javax.annotation.* | jakarta.annotation.* |
javax.transaction.* | jakarta.transaction.* |
javax.xml.bind.* | jakarta.xml.bind.* |
Automated Migration with IntelliJ IDEA
- Open your project in IntelliJ IDEA.
- Go to
Edit -> Find -> Replace in Files. - Search for
import javax.and replace withimport jakarta.. - Review each change carefully - not all
javaxpackages have moved to Jakarta (e.g.,javax.crypto,javax.net,javax.securityremain unchanged).
Automated Migration with OpenRewrite
Add to your pom.xml to use the official Spring Boot 3 migration recipe:
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.44.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>5.24.0</version>
</dependency>
</dependencies>
</plugin>
Run the migration:
mvn rewrite:run
Note: Always review the changes OpenRewrite makes before committing. Run your test suite afterwards.
Step 7 - Configuration Property Changes
Spring Boot 3 renamed and removed several configuration properties. Run the property migrator to identify issues.
7.1 Use the Spring Boot Properties Migrator (Temporary)
Add this dependency temporarily to your pom.xml to get migration hints at startup:
<!-- Add temporarily to identify deprecated properties -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
Start your application and check the logs - it will report any deprecated or renamed properties. Remove this dependency once all properties are migrated.
7.2 Common Property Changes
| Old Property | New Property |
|---|---|
spring.redis.* | spring.data.redis.* |
spring.mongodb.* | spring.data.mongodb.* |
spring.security.oauth2.resourceserver.jwt.jwk-set-uri | (unchanged) |
management.health.redis.enabled | management.health.redis.enabled (unchanged) |
spring.sleuth.* | management.tracing.* (Micrometer) |
spring.zipkin.* | management.zipkin.tracing.* |
7.3 Actuator Changes
Actuator endpoints are now under a different security model. Update your security configuration if you have custom actuator endpoint exposure:
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
tracing:
sampling:
probability: 1.0 # was: spring.sleuth.sampler.probability
Step 8 - Code-Level Changes
8.1 Spring Security Configuration
Spring Security 6 deprecated the WebSecurityConfigurerAdapter. Replace your security config class:
// BEFORE (Spring Boot 2.x pattern) - REMOVE
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated();
}
}
// AFTER (Spring Boot 3.x / Spring Security 6 pattern)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}
Key changes:
- Replace
extends WebSecurityConfigurerAdapterwith a@Bean SecurityFilterChain - Replace
authorizeRequests()withauthorizeHttpRequests() - Replace
antMatchers()withrequestMatchers()
8.2 Spring Data MongoDB Changes
If you use MongoTemplate or MongoRepository, no major code changes are needed. However:
@DBReflazy loading behavior has minor changes - test your MongoDB data access layer thoroughly.MongoAutoIndexCreationbehavior changed - ensure your@Indexed/@CompoundIndexannotations are intentional.
8.3 Resilience4j Migration (from Hystrix)
Replace @HystrixCommand with @CircuitBreaker:
// BEFORE (Hystrix)
@HystrixCommand(fallbackMethod = "fallbackGetUser")
public User getUser(String userId) { ... }
public User fallbackGetUser(String userId) { ... }
// AFTER (Resilience4j)
@CircuitBreaker(name = "userService", fallbackMethod = "fallbackGetUser")
public User getUser(String userId) { ... }
public User fallbackGetUser(String userId, Throwable t) { ... }
Add Resilience4j configuration to application.yml:
resilience4j:
circuitbreaker:
instances:
userService:
register-health-indicator: true
sliding-window-size: 10
minimum-number-of-calls: 5
permitted-number-of-calls-in-half-open-state: 3
wait-duration-in-open-state: 10s
failure-rate-threshold: 50
8.4 JAXB Runtime (if using XML binding)
JAXB was removed from the JDK in Java 11. If your service uses XML binding, add:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
Step 9 - Build & Validate
9.1 Clean Build
# Clean all cached artifacts and do a fresh build
mvn clean install -U
# If you encounter dependency resolution issues, force update snapshots
mvn clean install -U -Dsnapshot=true
9.2 Run Tests
# Run unit tests
mvn test
# Run all tests including integration tests
mvn verify
9.3 Check for Dependency Conflicts
# View the resolved dependency tree to spot conflicts
mvn dependency:tree
# Check for dependency conflicts specifically
mvn dependency:tree -Dincludes=org.springframework.security
# Detect duplicate classes from conflicting jars
mvn dependency:analyze
9.4 Start the Application Locally
mvn spring-boot:run
# Check startup logs for:
# 1. No warnings about deprecated properties (if you added spring-boot-properties-migrator)
# 2. Successful Spring context startup
# 3. No ClassNotFoundException or NoSuchMethodException
9.5 Validation Checklist
After your application starts successfully, verify the following:
- Application starts without errors
-
/actuator/healthreturnsUP - Authentication/token validation works end-to-end
- MongoDB connectivity is healthy
- All REST endpoints return expected responses
- Tracing headers (trace-id, span-id) appear in logs
- Circuit breakers are registered (visible in
/actuator/healthor Resilience4j metrics) - All unit and integration tests pass
Troubleshooting
The application logs to the standard output during startup. Examine the logs by running:
mvn spring-boot:run
Or check the container logs if deployed:
oc logs <pod>
(or)
kubectl logs <pod>
ClassNotFoundException: javax.servlet.http.HttpServletRequest
Cause: A dependency still brings in the old javax.servlet jar.
Fix: Search for the offending dependency and exclude javax.servlet-api or replace with jakarta.servlet-api:
mvn dependency:tree | grep javax.servlet
NoSuchBeanDefinitionException: ResourceServerTokenServicesConfiguration
Cause: spring-security-oauth2-autoconfigure has been removed.
Fix: Remove that dependency and follow Step 5.1 to use native Spring Security 6 OAuth2.
Error creating bean: OAuth2ResourceServerJwtConfiguration
Cause: JWT configuration is missing or incomplete after migrating from legacy OAuth2.
Fix: Ensure spring.security.oauth2.resourceserver.jwt.jwk-set-uri or issuer-uri is set in application.yml.
Compilation fails with cannot find symbol: class HttpMethod in Spring Cloud Gateway
Cause: Spring Cloud Gateway 4.x (part of 2025.0.0) changed some API classes.
Fix: Check for HttpMethod usage - it now comes from org.springframework.http.HttpMethod.
java.lang.IllegalArgumentException: Could not resolve placeholder '...' at startup
Cause: A property name changed in Spring Boot 3.
Fix: Add spring-boot-properties-migrator (see Step 7.1) to identify the renamed property, update your application.yml, then remove the migrator.
Embedded MongoDB tests fail with EmbeddedMongoAutoConfiguration
Cause: The old de.flapdoodle.embed.mongo is not compatible with Spring Boot 3.
Fix: Replace with de.flapdoodle.embed.mongo.spring30x as shown in Step 5.5.
Spring Cloud Sleuth traces no longer appear in logs
Cause: Sleuth is replaced by Micrometer Tracing.
Fix: Replace the Sleuth dependency with micrometer-tracing-bridge-brave (Step 5.2) and update Sleuth properties to Micrometer properties (Step 7.2).
@Transactional not working after upgrading
Cause: javax.transaction.Transactional import used instead of jakarta.transaction.Transactional.
Fix: Update all @Transactional imports from javax.transaction -> jakarta.transaction.
Build fails with Unsupported class file major version 65 (JDK mismatch)
Cause: Library compiled with JDK 21 but your build environment uses JDK 11 or older.
Fix: Ensure JDK 21 is active: java -version should show 21.x.x.
Support
If you encounter issues not covered in this guide, reach out through the following channels:
| Channel | Details |
|---|---|
| Platform Team | Raise a ticket in the shared service backlog |
| Azure DevOps Repo | xjw-workspace |
When filing a support request, please include:
- Your service name and repository link
- The COBRA library version(s) you are upgrading from/to
- The full Maven error output (
mvn clean install -e) - Your pom.xml