Open Rewrite basics

Modernisations are very exciting from a technical point of view. From the perspective of the project or product managers, however, things look different. The effort and possible risks cloud the picture here. This article presents Open Rewrite, a tool for reproducible, testable and efficient modernisations. By using Open Rewrite, large modernisations can be carried out elegantly and cost-effectively. The blog post provides a general overview of Open Rewrite. Two subsequent posts will focus on the development of custom migrations and their use at an organisational level.

Why automate migrations?

In his book Refactoring, Martin Fowler describes many small adjustments to existing source code with the aim of improving quality. He himself describes them as "small [...] behaviour preserving [...] canges, each too small to be worth doing". An example of refactoring according to Fowler is the removal of the SuppressWarnings annotation from a method. By removing a single line, compiler warnings become visible without changing the behaviour. The potential benefit for the product is small and remains so if this change is applied to the entire code base. However, the effort involved increases considerably, so the motivation to make this adjustment will never be particularly high.

The effect is even greater when updating frameworks such as Spring Boot. Here, the necessary adjustments are usually limited to replacing annotations, renaming parameters and updating dependencies. As the behaviour of the product ideally does not change, the benefit is again low. In addition, the risk of additional work increases due to the large number of customisations in different places. The reluctance to modernise the framework therefore continues to grow.

The creation and productive implementation of software artefacts is in a similar area of conflict. Continuos Integration/Continuos Deployment with automated pipelines has established itself as a solution here. The starting point for this solution was the development of tools to automate the tasks. In the context of software modernisation, Open Rewrite is an open source automation solution for migrations that enables a similar approach.

Open Rewrite is an open source tool for large-scale automated source code migrations. With Open Rewrite, customisations to existing source code can be defined and efficiently executed on large code bases. The automation makes customisations repeatable and can be transferred to other products. The test-driven development approach also reduces the risk of incorrect migrations. The active community offers extensive support in the event of problems and ensures rapid further development. Moderne stands behind the open source product and offers additional services for companies. The open source resources are sufficient for most applications.

Technologically, Open Rewrite is a tool from the Java ecosystem, and the number of supported languages and ecosystems has grown rapidly in recent years. The tool reads the existing source code like a developer, taking into account not only the syntax but also the semantics. Predefined changes are made on the basis of the information read in. The definition of these changes is referred to as recipes. During the transformations, only the necessary changes are made to the source code and the defined style is adhered to. Just as experienced developers do.

How do I find the right migrations?

All available recipes are documented on the Open Rewrite project page under Recipe Catalogue. The recipes are grouped by topic, programming language and framework. The possible configurations are listed for each recipe. For recipes that consist of several steps, all recipes used are listed and the options for execution with Maven or Gradle are specified directly. For our next example, we will look in the Spring category.

Example migration to Spring Boot 3.2

To see Open Rewrite in action and get our own idea of its capabilities, we need a codebase. In this example, Spring Boot Pet Clinic is used. This sample project from the Spring Boot community is well-known to many, is constantly updated and covers many basic technological building blocks. In order to have a realistic migration effort, the project is reset to Spring Boot 2.7 (01.09.2022, dgcd, 276880ed). The aim of this example is to migrate to Spring Boot 3.2.

The migration from Spring Boot 2.7 to Spring Boot 3.2 consists of many individual steps. These steps are regularly described by the Spring Boot team in the migration instructions. In addition, the team supports the development of the migration scripts for Open Rewrite. The resulting migrations are summarised in the recipe catalogue in the Java/Spring/Boot3 category.

The Migrate to Spring Boot 3.2 recipe is particularly interesting for our migration. In addition to some class changes, the migrations to String Cloud, Spring Security and Virtual Threads are particularly noticeable. This gives an idea of the actual scope of the migration. To minimise the effort for developers, the recipe ensures that the application is first migrated to Spring Boot 3.1. This migration chain can be traced back to Spring Boot 2.0. This means that migrations that were forgotten at an earlier point in time are also carried out. To start the migration, the CLI variant of Maven is used.

	
		$ mvn -o org.openrewrite.maven:rewrite-maven-plugin:run \
		     -Drewrite.recipeArtifactCoordinates=\
		 	org.openrewrite.recipe:rewrite-spring:RELEASE \
		     -Drewrite.activeRecipes=\
		 	org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2
	

This variant requires the fewest adjustments to the project and is particularly compact. After a few minutes, the automatic migration is complete and 18 files have been migrated. In addition to the application classes, these files also include the pom.xml and the contained GitHub actions. However, an initial build of the project fails.

Problems occur time and again during the development of software, and Open Rewrite is not exempt from them despite its high test coverage. However, some of these problems are caused by the users. For example, the first build after migration fails because the formatting is not correct. Thanks to the spring-javaformat-maven plugin, this problem can be quickly resolved with the Goal apply. Alternatively, a suitable style could have been configured in Open Rewrite.

Another build attempt fails due to a bug in Open Rewrite. The dependency jakarta.xml.bind:jakarta.xml.bind-api is used, but is not declared in the pom.xml. If the dependency is added, the project can be successfully built and tested.

Conclusion

These two challenges should be able to be solved by any developer with Spring Boot experience in a short time. By using Open Rewrite, the effort required to migrate from Spring Boot 2.7 to Spring Boot 3.2 was reduced to less than an hour. A manual migration would have required significantly more effort. In addition to the major Java frameworks Spring, Quarkus and Jakarta EE, Open Rewrite also supports Javascript and Node.js, Python, Terraform and many other technologies from modern and legacy software systems. Thanks to the large pool of existing recipes, many large migrations can be carried out efficiently with Open Rewrite. If adaptations or new recipes are required, these can be developed in a test-driven and customised manner.

These advanced topics will be covered in more detail in two further blog posts.

Would you like to find out more about exciting topics from the world of adesso? Then take a look at our previous blog posts.

Picture Merlin Bögershausen

Author Merlin Bögershausen

Merlin Bögershausen is a software developer, speaker and author at adesso in Aachen. He deals with innovations in the Java universe and software development in the public sector.

Save this page. Remove this page.