Introducing Spring Boot Migrator

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

About the Author

Subscribe for MMS Newsletter

By signing up, you will receive updates about our latest information.

  • This field is for validation purposes and should be left unchanged.