OpenRewrite: The Smartest Way to Tackle Tech Debt

Denuwan Himanga Hettiarachchi
3 min readJan 11, 2025

Addressing technical debt in modern software engineering is crucial, particularly when it comes to mitigating security vulnerabilities. With the increasing prevalence of data breaches and security threats in our daily lives, tackling this challenge has become more critical than ever.

On the other hand, managing technical debt is both complex and time-consuming — a seemingly never-ending loop. The effort required to update projects can be substantial. Since we’re often dealing with in-flight projects, it’s not feasible to simply halt everything for migrations or to deprioritize business features in favor of addressing technical debt. Unfortunately, technical debt often remains invisible to non-technical stakeholders — until, of course, a data breach occurs or a company faces bankruptcy as a result.

Sometimes, our systems may be vulnerable due to dependencies that aren’t directly used in our projects. While tools like GitHub Code Scanning can help identify these hidden vulnerabilities, addressing them often requires significant manual effort, making the process both time-intensive and complicated.

In this tutorial, I’ll introduce OpenRewrite, a powerful tool that simplifies refactoring with minimal effort. With just a single command-line operation, you can keep your project up to date, saving time and effort while maintaining security and code quality.

Refactoring Your Project With OpenRewrite

OpenRewrite is a game-changer when it comes to tackling technical debt. Released under the Apache License and fully open-source, OpenRewrite primarily focuses on the Java ecosystem but is gradually expanding to support other areas of software engineering.

OpenRewrite offers IDE plugins with built-in functionalities. However, in this tutorial, I’ll demonstrate how to use OpenRewrite in a Maven project to migrate a Spring Boot application. To perform the upgrade, you’ll need a basic understanding of a few core concepts in OpenRewrite.

In this demo, I’m using a Spring Boot 2.x.x project that I developed five years ago with Java 8.

> git clone https://github.com/Denuwanhh/spring-audit-demo.git

Identify Recipes

In OpenRewrite, recipes act as the “switches” that determine the output of the refactoring process. Simply put, your project is the input, and a recipe is the configuration that defines what changes need to be applied. OpenRewrite’s documentation includes popular recipes such as Migrate to Java 17 and Migrate to Spring Boot 3 from Spring Boot 2. You can select a recipe based on your specific requirements and start your migration process.

Recipes often consist of multiple actions to achieve a complete migration. For example, the “Migrate to Spring Boot 3 from Spring Boot 2” recipe doesn’t just handle Java library upgrades — it may also update your source code to align with the requirements of the newer version.

In this demo, I’ll apply two recipes: one to upgrade the Java version and another to upgrade the Spring Boot version. Since I’m using a Maven project, I’ll add the following plugins to the pom.xml file and simply run the Maven action to initiate the process.

Recipe #1: Migrate to Java 17

Add the following plugins to the pom.xml file and simply run the Maven mvn rewrite:run action to initiate the process.

<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.0.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.migrate.UpgradeToJava17</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-migrate-java</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

Recipe #2: Migrate to Spring Boot 3 from Spring Boot 2

Add the following plugins to the pom.xml file and simply run the Maven mvn rewrite:run action to initiate the process.

<project>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.0.0</version>
<configuration>
<exportDatatables>true</exportDatatables>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>6.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

I won’t go into detail about the changes that occur during the migration. However, you can check out this pull request where I merged the feature-version-upgrade branch into my master branch. It provides a clear view of the files that were updated during the migration and the resulting behavior.

Additionally, you’ll notice that the 111 Dependabot alerts previously present on the main branch were resolved after merging the feature-version-upgrade branch into master.

Happy coding…

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Denuwan Himanga Hettiarachchi
Denuwan Himanga Hettiarachchi

Written by Denuwan Himanga Hettiarachchi

Blogger, Freelance Writer, and Tech Lead based in Colombo, SL.

No responses yet

Write a response