New features in Spring Boot 3 and Spring 6 and Upgrade to Spring boot 3 and Java 17
The main features or changes introduced in spring 6 are as follows
1. Java 17 baseline
Anyone using Java 8 or Java 11 must upgrade their JDK to 17 or above before they can develop Spring Boot 3.0 applications. Although JDK 17 is the latest long-term support release for the Java SE platform, Spring Boot 3.0 has also been tested and works well with JDK 17
1.1 Record
The record was introduced in Java14.
In the past, we needed to write a bunch of gets and set methods to write a class. Later Lombok, these methods were saved. Now Java provides us with native writing methods.
public record User() {}
In essence, the class modified by record is final, and its parent class is not Object, but java.lang.Record.
Record class properties can only be declared in the header, all member variables are public final, and only static properties can be declared, but member methods and static methods can be declared.
public record User(String username) {
static int id;
public String getName(){
return this.username;
}
}
1.2 Text blocks
Text blocks were introduced in Java13 and made permanent in Java15.
In the past, when we copied a multi-line string to Java, line terminators would be added automatically.
String sql = "SELECT\n" +
"\t* \n" +
"FROM\n" +
"\tsys_user0 \n" +
"WHERE\n" +
"\tuser_name = 'abc'";
The text block function can help us more conveniently define a string literal containing multiple lines of text, which uses triple quotation marks as the start and end separators.
String sqlBlock = """
SELECT
*
FROM
sys_user0
WHERE
user_name = 'abc'
""";
1.3 Switch expression
Switch expressions were introduced in Java12 and made permanent in Java14.
The upgraded switch contains two features, one is to allow the case to use multiple constants, and the other is to have a return value.
The new case x-> syntax is more concise in use, and there is no need to write a break for each case.
String name = "Tom";
int ret = switch (name) {
case "A" -> 1;
case "Tom", "Jack" -> 2;
default -> 0;
};
1.4 Pattern Matching Pattern Matching
Pattern matching can help us simplify our instanceofcode.
if (obj instanceof String s) {
System.out.println(s.toLowerCase());
}
Can also be used in switch-case statements:
static double getDoubleUsingSwitch(Object o) {
return switch (o) {
case Integer i -> i.doubleValue();
case Float f -> f.doubleValue();
case String s -> Double.parseDouble(s);
default -> 0d;
};
}
1.5 Sealed sealed class
Sealed was introduced in Java15 and became a permanent feature in Java17.
The main function of the sealed class is to limit the inheritance of the class.
For example, we have the Animal class, Dog and Cat inherit it respectively, and implement the eat method. Their eating actions are different, but we don’t want people to inherit the Animal, and he is not allowed to inherit the animal’s eating behavior, just like the following This restricts it to be a sealed class through the sealed and permits keywords, and only cats and dogs can inherit it.
It should be noted that the subclass must be sealed, non-sealed or final after the parent class is defined as sealed.
public abstract sealed class Animal permits Cat, Dog {
public abstract void eat();
}
public non-sealed class Dog extends Animal{
@Override
public void eat() {
System.out.println("dog eat");
}
}
public non-sealed class Cat extends Animal{
@Override
public void eat() {
System.out.println("cat eat");
}
}
2. Support for generating native images with GraalVM
Spring Boot 3.0 applications can now be converted into GraalVM native images, which have a smaller memory footprint and can significantly improve startup performance.
3. Improved observability with built-in support for distributed tracing
Spring 6 included an observability initiative that resulted in a new Micrometer Observation API and the migration of the former Spring Cloud Sleuth project to Micrometer Tracing. This enables more efficient recording of application metrics and tracing through providers such as OpenZipkin or OpenTelemetry.
4. Support for Jakarta EE 10 with an EE 9 baseline
Spring Boot 3.0 has completed the migration from Java EE to Jakarta EE APIs for all dependencies.
5. Upgrade to Spring Boot 3 and Java 17
5. Preparing for Java 17 Support
5.1 Upgrade Maven Compiler Plugin
To support Java 17, ensure that your Maven compiler plugin is at least version 3.5.4. Adjust your pom.xml as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
5.2 Update Spring Boot Specification
Upgrade your Spring Boot Specification and dependencies to reflect the change in Java version.
Upgrade Spring Boot Specification
Start by upgrading your Spring Boot Specification and dependencies. The spring-boot-starter-parent in your pom.xml allows you to configure default plugins and properties, including the Java version. Override the default version to Java 17 as shown below:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version> <!-- Update to the latest version -->
<relativePath />
</parent>
Override the parent POM’s default Java version property as shown:
Recommended by LinkedIn
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<sap.cloud.security.version>3.0.1</sap.cloud.security.version>
</properties>
5.2. Upgrading Dependencies
5.2.1 Maven Dependency Tree
Upgrading dependencies can be a challenging task due to potential conflicts. The Maven Dependency Tree can help you understand your project’s dependencies and resolve conflicts caused by different versions of a dependency.
Use the following command in the terminal to print the project’s dependency tree:
mvn dependency:tree
5.2.2 Resolving Conflicts in Verbose Mode
To identify any incompatibility issues with a JAR, use the verbose mode:
mvn dependency:tree -Dverbose
5.2.3 Including and Excluding Dependencies
Use the -Dincludes and -Dexcludes options to include or exclude specific dependencies from the output. For example:
mvn dependency:tree -Dincludes=org.springframework.*
5.2.4 Saving Dependency Tree to a File
Save the dependency tree output to a file for easier validation:
mvn dependency:tree -DoutputFile=project-dependencies.txt
5.2.5 Leveraging Maven Dependency Tree in Eclipse
Instead of relying solely on the terminal, you can use the Maven Dependency Tree in the Eclipse IDE. The “Dependency Hierarchy” tab in the pom.xml shows the tree with verbose output and resolved dependencies.
5.3. Hibernate 6.X Migration in Spring Boot 3.0
Hibernate 6.1 is used in Spring Boot 3.0 by default, and it’s essential to follow the detailed migration guides to ensure a smooth application migration.
5.4 . Changes in URL Matching for WebFlux and Spring MVC
The trailing slash matching configuration option has been deprecated and set to false as of Spring Framework 6.0..
5.5. Handling Lombok
Ensure Lombok compatibility with Java 17 by upgrading it to version 1.18.24. Remember that upgrading Lombok to version 1.18.16 or later requires adding the lombok-mapstruct-binding annotation processor to the maven-compiler-plugin configuration.
Add the annotation processor to the maven-compiler-plugin as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
5.6. Rewriting Security Configuration
Update your security configuration to support the changes introduced in Spring Boot 3.0.0 as shown in
You might need to rewrite your Security Configuration for Spring Boot 3.0. Example:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorizeReq -> authorizeReq
.requestMatchers("/**").hasAuthority("Admin")
.anyRequest().denyAll())
//...
// Add other configurations as needed
);
5.7. Replace javax to jakarta Packages
Since Spring Boot 3.0.0 supports Jakarta EE 9 and 10, you’ll need to change the packages from javax.* to jakarta.*. Update your imports accordingly.
5.8. SAP Specific: SAP BTP Spring XSUAA Security Library
The spring-xsuaa library is deprecated, and you should switch to its successor, the spring-security library. Update your dependencies as follows:
<dependency>
<groupId>com.sap.cloud.security</groupId>
<artifactId>java-bom</artifactId>
<version>3.0.1</version>
</dependency>
<!--
Refer latest version here
https://github.com/SAP/cloud-security-services-integration-library/blob/main/pom.xml
-->
<dependency>
<groupId>com.sap.cloud.security</groupId>
<artifactId>resourceserver-security-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>spring-security-compatibility</artifactId>
</dependency>
<!-- OAuth2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
As part of the upgrade, some SAP-specific dependencies related to SAP BTP Spring XSUAA Security Library need to be removed or replaced. Below are the changes required:
5.9.1 Remove Deprecated Dependencies
Remove the deprecated spring-xsuaa & following dependencies:
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>spring-xsuaa</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>xsuaa-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.sap.xs2.security</groupId>
<artifactId>java-container-security</artifactId>
</dependency>
<dependency>
<groupId>com.sap.xs2.security</groupId>
<artifactId>java-container-security-api</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>java-container-security-api</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>xsuaa-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>spring-xsuaa-mock</artifactId>
</dependency>
Additionally, ensure that you avoid referencing any other SAP-internal security library with group-id com.sap.security or com.sap.security.nw.sso.*. These libraries may not be compatible with the upgraded versions of Java and Spring Boot.
5.9.2. Configuring Buildpacks
Configure the JBP_CONFIG_OPEN_JDK_JRE to ensure Java 17 compatibility:
JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 17.+ } }'