Saturday, November 26, 2022

Spring Boot 3 : New features and migration

Spring Framework 6, released on November 2022, is the major version change and has many high-impacting features, changes and upgrades into the Spring development ecosystem. Similarly, Spring boot 3 is a major version upgrade after 4.5 years of Spring boot 2. Released on November 2022, Spring boot 3 is based on Spring Framework 6 and has lot of changes. In this article we will go through the features and migration approach to Spring boot 3.

1. New Features in Spring Framework 6

The main features or changes introduced in spring framework 6 are as follows:

  • Upgraded baseline Java version to Java 17. Although Java 17 was already supported it has now become the baseline version. It is an LTS (Long-term Supported) version with all the new features introduced in recent Java versions such as records, instanceof changes, multiline strings etc.
  • Replaced Java EE with Jakarta EE; the minimum supported version is Jakarta EE9. This breaks backward compatibility and is the source of most issues in the migration process. It will use the jakarta packages namespace instead of javax namespace.
  • Expect first-class support for JPMS (Java Platform Module System) which will allow more strict accessibility in the application code and libraries. Although full JPMS support may not arrive with the initial release but may come at a later date.
  • Enhanced support for native compilation, a move towards making cloud-native applications more efficient. It is in response to newer frameworks such as Quarkus and Micronaut that produce native applications with low memory usage and fast start-up times. Though we can do native compilation today using spring-native module, with Spring boot 3 we can seamlessly integrate with a starter configuration and specific build commands.
  • Bakes observability into Spring to further encourage cloud-native development. Unlike agent-based observability, it records metrics with Micrometer and offers tracing through providers such as OpenZipkin or OpenTelemetry.
  • Native support for declarative HTTP client interface using @HttpExchange annotations.
  • New ProblemDetail API for compliance with Problem Details for HTTP APIs specification [RFC 7807]. 
  • Drops several outdated features and third-party integrations.
  • Additionally, in the future, Spring 6 will adopt more exciting features such as Project Loom while retaining a JDK 17 baseline.

2. New Features in Java 17

  • Records in Java 17 are classes that act as a transparent carriers for immutable data. In other words they are Plain Old Java Objects (POJO) or Data Transfer Objects (DTO). They can be easily created as below:

public record Person (String name, String address) {}

  • Text Blocks in JEP 378, makes it possible to create multi-line text blocks without the need to concatenate strings on line breaks:
String textBlock = """
Hello, this is a
multi-line
text block.
""";

  • Switch Expressions in JEP 361, which (like all expressions) evaluate a single value, and can be used in statements. Instead of combining nested if–else-operators (?:), we can now use a switch–case-construct:
DayOfWeek day = DayOfWeek.FRIDAY;
int numOfLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

  • Pattern Matchings were elaborated in Project Amber and found their way to the Java Language. In the Java Language, they can help to simplify the code for instanceof evaluations. We can use them directly with instanceof:

if (obj instanceof String s) {
    System.out.println(s.toLowerCase());
}
System.out.println(s.toLowerCase());
}

  • Sealed classes can limit inheritance by specifying allowed subclasses:
public abstract sealed class Car permits Kia, Honda {}

2. New Features in Spring boot 3

As Spring boot 3 will use Spring 6, so all the above changes automatically apply to Spring boot 3 applications as well, plus a few more. Sping boot 3 will also have an out-of-the-box support for Native Java compilation for GraalVM. A big change is that Spring Boot 3 will remove all deprecated features. For example, in Spring boot 2.4, configuration properties processing had changed in incompatible ways and to fix it, the use of spring.config.use-legacy-processing=true was suggested. So make sure this property is not in your code.

3. Migration

The Spring Boot Migrator (SBM) can be helpful in migrating a Spring Boot 2.7 application to version 3.0 and a Spring Boot 2.6 application to version 2.7. It does static analysis of application source code and provides recipes for automated migrations. Note that it is an experimental project for converting non-Spring boot applications to Spring boot application, and upgrading existing Spring boot applications to the latest versions.

3.1. Upgrade Java Version

As Java 17 is the new baseline in new Spring versions, start with migrating your applications to Java 17 first with your current Spring versions and existing codebase. Make sure it all works perfectly by running all the unit tests. This is where the unit tests really help in identifying the breaking changes in time.

3.2. Upgrade to Latest Version of Spring 5 and Spring boot 2

In the second step, migrate your application to the most recent versions of Spring 5 and Spring boot 2. This is the official recommendation also. It will help you narrow down the breaking changes that will come with the major version updates of Spring 6 and Spring Boot 3. Again run all application tests and ensure you fix all the issues you may see at this step. At this step, make sure you get rid of all deprecated classes, methods and properties because those have been removed in Spring boot 3.

3.3. Upgrade to Spring 6 and spring Boot 3

Next, change the versions to Spring framework 6 and fix the following issues one by one. Note that these changes may require the code changes in the application code such as import statements and bean initializations.

Spring Boot 3 depends upon a Jakarta EE 9 specification. For example, Spring Boot 3 uses Servlet 5.0 and JPA 3.0 specifications. When using Spring boot starters, Spring boot will resolve the correct versions of library for you. But if you have imported some libraries, you need to look for the new artifacts that generally end with -jakartaee9 or -jakarta.

3.4. Fix Import Statements

This change will require you to rename all javax.* imports to jakarta.* imports. Begin with changing the classes and interfaces under “javax.” to jakarta. in all places. The intent is to all javax classes to jakarta classes to keep your application future-safe.

For data access later, switch your javax.persistence imports to jakarta.persistence classes and upgrade the hibernate version to minimum Hibernate ORM 5.6.x, supporting Jakarta persistence. By default, Spring Boot 3 will use Hibernate 6 and Flyway 9.

If you are deploying your application to applications servers such as TomcatJetty or Undertow then make sure you upgrade their minimum versions supporting Jakarta EE 9. Also, you will need to switch the javax.servlet imports to jakarta.servlet.

3.5. API-Specific Changes

  • Spring MVC and Spring WebFlux no longer detect controllers based solely on a type-level @RequestMapping annotation. We must specify the @Controller or @RestController annotations. Check out your web controllers once more.
  • You will need to upgrade to Apache HttpClient 5 if you use RestTemplate to make REST calls to remote endpoints.
  • As HttpMethod is a class and no longer an enum, you may need to change your code if you use these enums directly instead of using the public APIs. The public APIs have no change.
  • You may also need to increase the Log4j2 version if you have added it explicitly. The automatically imported version is Log4j 2.18 at the time of writing this post.

3.6. Changes in Default Behavior

There might be few changes in the default behavior of specific features. We need to wait until the release changes are finalized. For example, the default format for the date and time component of log messages for Logback and Log4j2 has changed to align with the ISO-8601 standard which is yyyy-MM-dd'T'HH:mm:ss.SSSXXX. The LOG_DATEFORMAT_PATTERN environment variable or logging.pattern.dateformat property can be used to restore the previous default value of yyyy-MM-dd HH:mm:ss.SSS.

3.7. Check out for Deprecated Libraries

Finally, check out the support for external libraries that require Spring boot support. Either upgrade their versions to Jakarta EE 9 equivalent artifact or wait for some time to get upgraded. For example, Spring boot 3 now supports REST AssuredJerseyH2 and EhCache 3, but it still does not support Apache ActiveMQInfinispanPooled JMSJolokia and SMTP appending of logs at the time of writing this post.

4. Conclusion

This post taught us about the new exciting features introduced in Spring 6 and Spring boot 3. My recommendation is to go slow and follow a well-prepared migration plan. A few migration steps are listed in this post; a few will be totally unexpected and vary application-to-application. You will identify them as you start the migration process.

Finally, keep checking the official migration guide by spring team for the latest changes suggested by them.

No comments:

Post a Comment