MMS • Johan Janssen
Article originally posted on InfoQ. Visit InfoQ
Spring Boot Migrator (SBM) is an experimental Spring project first released in March 2022. SBM allows developers to convert existing, non Spring Boot applications, which are based on technologies such as JAX-RS, EJB and JMS to Spring Boot or upgrade older Spring Boot applications to the latest version.
SBM is based on OpenRewrite, a general purpose tool for source code and configuration refactoring. OpenRewrite uses Recipes to change existing files for Kubernetes, Gradle, Maven, Java and others. The recipes allow, for example, to upgrade an existing application to a newer version of Java. SBM uses OpenRewrite specifically for Spring Boot migrations.
After downloading the latest version of SBM, the command-line interface (CLI) can be started with:
java -jar spring-boot-migrator.jar
After a few seconds, the user is presented with an SBM-specific prompt: migrator:>
.
The list
command displays the thirty recipes currently available. The recipes, for example, support upgrading Spring Boot to a new version, change XML Bean configuration to Java configuration and migrate various Java EE / Jakarta implementations to Spring Boot.
With the scan [directory]
command, an application is analyzed and the applicable recipes are displayed. The following shows an example, older JAX-RS application without Spring Boot support analyzed by SBM, displaying the following results:
scanning 'JAXRS'
Checked preconditions for '.../JAXRS'
[ok] Found pom.xml.
[ok] 'sbm.gitSupportEnabled' is 'true', changes will be committed to branch [master] after each recipe.
[ok] Required Java version (17) was found.
[ok] Found required source dir 'src/main/java'.
Maven 100% │███████████████████████████│ 2/2 (0:00:09 / 0:00:00)
Applicable recipes:
= 'automated recipe'
= 'partially automated recipe'
= 'manual recipe'
- initialize-spring-boot-migration []
-> Initialize an application as Spring Boot application.
- migrate-jax-rs []
-> Any class has import starting with javax.ws.rs
- cn-spring-cloud-config-server []
-> Externalize properties to Spring Cloud Config Server
Based on the source code of the application, SBM displays the recipes matching the preconditions. When no recipe matches, the list of applicable recipes will remain empty. In this case, one of the recipes listed above may be applied, for example to convert the existing code to a Spring Boot application:
migrator:> apply initialize-spring-boot-migration
This results in a new Git commit with the description SBM: applied recipe ‘initialize-spring-boot-migration’.
Analyzing the commit shows the following changes in the pom.xml: the packaging was changed from WAR to JAR, the spring-boot-starter
and spring-boot-starter-test
dependencies and the spring-boot-maven-plugin
were added and the dependencyManagement
section now contains the spring-boot-dependencies of type pom. Depending on the original indentation of the pom.xml file, the indentation may change as well to reflect the recipe.
The source code was altered as well and now contains a SpringBootApp.java and a SpringBootAppTest.java:
@SpringBootApplication
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
@SpringBootTest
class SpringBootAppTest {
@Test
void contextLoads() {
}
}
Now the application is converted to a Spring Boot application. The next step is to migrate the JAX-RS source code to Spring Boot with the command:
migrator:> apply migrate-jax-rs
The command results in a new Git commit with the description: SBM: applied recipe ‘migrate-jax-rs’. Analyzing the commit shows the JAX-RS imports were removed and replaced with Spring imports and the JAX-RS @Path
annotation on the class file was replaced with the Spring Boot @RestController
and @RequestMapping
. The various methods now have Spring Boot’s @RequestMapping
, @RequestParam
, @PathVariable
instead of the JAX-RS annotations such as @Get
, @Post
, @Path
, @Produces
, @QueryParam
and @PathParam
. Lastly the return type of the methods is no longer of type Response
, but of type ResponseEntity
.
Running the Spring Boot application after the migrations unfortunately failed as the maven-compiler-plugin defined in the pom.xml file used an older version of Java. Manually changing the pom.xml to use the currently installed Java version fixes the problem, but it’s also possible to automate the step with the Change Maven plugin configuration of OpenRewrite.
Analyzing the resulting code and configuration showed some dependencies which were no longer needed by Spring Boot. The obsolete dependencies may be removed manually or this step may be automated as well with SBM or OpenRewrite.
SBM currently supports Maven as OpenRewrite’s support for Gradle is not yet complete. More information on SBM can be found in the User Documentation and Developer Documentation.