Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Accessibility testing is a crucial aspect to ensure that your application is usable for everyone and meets accessibility standards that are required in many countries.

By automating these tests, teams can quickly detect issues related to screen reader compatibility, keyboard navigation, color contrast, and other aspects that could pose a barrier to using the software effectively for people with disabilities.

Learn how to automate accessibility testing with Selenium and the LambdaTest cloud-based testing platform that lets developers and testers perform accessibility automation on over 3000+ real environments:

Automated Accessibility Testing With Selenium

1. Overview

OpenRewrite is a refactoring ecosystem for Java and other source code. Sometimes, we need to upgrade dependencies to the latest versions, apply security patches, eliminate the use of a deprecated API, migrate from one technology to another (e.g., JUnit asserts to AssertJ), etc. We can use the OpenRewrite library to address these challenges. In this tutorial, we’ll discuss the basics of the OpenRewrite project and show some examples of how it can be used in practice. In every case, we’ll use the Spring PetClinic application.

2. OpenRewrite Basics

Here are some of the common types of upgrades we can perform with OpenRewrite:

  • Language Upgrades: migrating from an older version of a language to a newer version, such as Java 8 to Java 11 or beyond.
  • Framework Upgrades: adapting to newer versions of frameworks like Spring Boot, Hibernate, etc.
  • Dependency Migration: upgrading from one library version to another when there are breaking changes.
  • Security Patching: replacing vulnerable methods or libraries with secure alternatives.
  • Custom Transformations: any transformation specific to our business logic or infrastructure.

2.1. OpenRewrite Recipes

The main feature of OpenRewrite is that it will automatically refactor source code by applying recipes to the project. OpenRewrite comes with a variety of built-in recipes for common transformations, and the community often contributes recipes for widespread tasks. Each recipe can perform specific refactoring tasks. These recipes are written in Java code and included in the build process using the OpenRewrite Maven or Gradle plugin. In this tutorial, we’ll focus on the Maven plugin.

2.2. Maven Dependency

Let’s start by importing the rewrite-maven-plugin plugin in the <plugins> section of the pom.xml:

<plugin>
    <groupId>org.openrewrite.maven</groupId>
    <artifactId>rewrite-maven-plugin</artifactId>
    <version>5.8.1</version>
    <configuration>
        <activeRecipes>
        // Define the recipes 
        </activeRecipes>
    </configuration>
    <dependencies>
        // Dependencies for recipes
    </dependencies>
</plugin>

The <activeRecipes> tags specify which OpenRewrite recipes should be active when the plugin runs. Also, we can define any additional dependencies that the plugin might need. This can be particularly useful if certain recipes require external libraries or specific versions of libraries.

2.3. Checkout Spring PetClinic

Let’s check out the relevant branch of Spring PetClinic locally:

git clone https://github.com/spring-projects/spring-petclinic.git;
cd spring-petclinic;
git switch -c 2.5.x 1.5.x;

Here, the Java and Spring Boot versions are 8 and 1.5, respectively. In the next sections, we’ll go through the most widely used recipes.

3. Upgrading Spring Boot

Upgrading a Spring Boot project can be a complex task, depending on the changes between the version we’re currently using and the version we want to upgrade to. However, using OpenRewrite can help us navigate the process smoothly. Let’s upgrade the PetClinic project from Spring Boot 1.5 to 2.7.

3.1. Maven Dependency

Let’s add the UpgradeSpringBoot_2_7 recipe to the <activeRecipes> section in the rewrite-maven-plugin plugin:

<activeRecipes>
    <recipe>org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7</recipe>
</activeRecipes>

Also, we need to declare the rewrite-spring dependency to the <dependencies> section of our plugin:

<dependency>
    <groupId>org.openrewrite.recipe</groupId>
    <artifactId>rewrite-spring</artifactId>
    <version>5.0.11</version>
</dependency>

Note that to upgrade to Spring Boot 3, we need to use the UpgradeSpringBoot_3_0 recipe.

3.2. Run Spring Boot Upgrade Recipe

Now, we’re ready to execute the migration by running this command:

mvn rewrite:run

Below, we can see the results of Maven:

[INFO] --- rewrite-maven-plugin:5.8.1:run (default-cli) @ spring-petclinic ---
[INFO] Using active recipe(s) [org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7]
[INFO] Using active styles(s) []
[INFO] Validating active recipes...
[INFO] Project [petclinic] Resolving Poms...
[INFO] Project [petclinic] Parsing source files

Here, we see that Maven lists active recipes and applies the pom and source file changes. After running the recipe, OpenRewrite provides a list of changes. We can inspect the results with git diff:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
-   <version>1.5.4.RELEASE</version>
+   <version>2.7.14</version>
</parent>

As we can see here, the spring-boot-starter-parent version has been upgraded to 2.7.14. In addition, the @Autowired has been removed from some of our Java classes during the upgrade process:

-import org.springframework.beans.factory.annotation.Autowired;
class VetController {

    private final VetRepository vets;

-   @Autowired
    public VetController(VetRepository clinicService) {
        this.vets = clinicService;
}

Note that in Spring Boot 2.x and above, if a class has a single constructor, it will automatically be used for autowiring without needing the @Autowired annotation. When we upgrade to a newer version of Spring Boot, many of the managed dependencies, including JUnit, may get upgraded as well. Spring Boot 2.x defaults to using JUnit 5, whereas Spring Boot 1.5 was aligned with JUnit 4. This means there’s an expected change in how tests are structured and run. Depending on our needs, we can just upgrade JUnit without upgrading Spring Boot. In the next section, we’ll see how to migrate from JUnit 4 to JUnit 5.

4. Upgrading to JUnit5

JUnit is the de facto standard for unit testing in Java applications. OpenRewrite supports migrating from JUnit 4 to its successor JUnit 5.

4.1. Maven Dependency

Let’s activate the JUnit5BestPractices recipe in our pom.xml:

<activeRecipes>
    <recipe>org.openrewrite.java.testing.junit5.JUnit5BestPractices</recipe>
</activeRecipes>

Also, we need to declare the rewrite-testing-frameworks dependency to the <dependencies> section of our plugin:

<dependency>
    <groupId>org.openrewrite.recipe</groupId>
    <artifactId>rewrite-testing-frameworks</artifactId>
    <version>2.0.12</version>
</dependency>

4.2. Run JUnit Upgrade Recipe

Now, we execute the migration by running the mvn rewrite:run command. This command is completed in about a minute and migrates all tests to JUnit 5, as well as updating the pom.xml:

-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;


-    @Before
-    public void setup() {
+    @BeforeEach
+    void setup() {
         this.petTypeFormatter = new PetTypeFormatter(pets);
     }

-    @Test(expected = ParseException.class)
-    public void shouldThrowParseException() throws ParseException {
-        Mockito.when(this.pets.findPetTypes()).thenReturn(makePetTypes());
-        petTypeFormatter.parse("Fish", Locale.ENGLISH);
+    @Test
+    void shouldThrowParseException() throws ParseException {
+        assertThrows(ParseException.class, () -> {
+            Mockito.when(this.pets.findPetTypes()).thenReturn(makePetTypes());
+            petTypeFormatter.parse("Fish", Locale.ENGLISH);
+        });
     }

OpenRewrite updates not just the imports and @Test annotations, but also method visibility, applies MockitoExtension, and adopts assertThrows(). In general, OpenRewrite can help JUnit migration with tasks such as:

  • Updating annotations, e.g., changing @Before to @BeforeEach or @After to @AfterEach.
  • Modifying assertion method calls to align with JUnit 5’s syntax.
  • Removing or replacing JUnit 4 specific features with their JUnit 5 counterparts.
  • Updating import statements from JUnit 4 packages to JUnit 5 packages.

5. Upgrading to Java 11

Upgrading an older source code to Java 11 can be a challenging and time-consuming issue. In this section, we’ll use OpenRewrite to perform an automated migration from Java 8 to Java 11.

5.1. Maven Dependency

To upgrade Java, we need a different dependency and recipe. Let’s add the Java8toJava11 recipe to the <activeRecipes> section:

<activeRecipes>
    <recipe>org.openrewrite.java.migrate.Java8toJava11</recipe>
</activeRecipes>

Also, we need to declare the rewrite-migrate-java dependency to our plugin:

<dependency>
    <groupId>org.openrewrite.recipe</groupId>
    <artifactId>rewrite-migrate-java</artifactId>
    <version>2.1.1</version>
</dependency>

Note that to upgrade to Java 17, we need to use the UpgradeToJava17 recipe.

5.2. Run Java Upgrade Recipe

To upgrade the Java, we can apply the mvn rewrite:run command. After that, we’ll see output like:

[INFO] Using active recipe(s) [org.openrewrite.java.migrate.Java8toJava11]
[INFO] Running recipe(s)...
[WARNING] Changes have been made to pom.xml by:
[WARNING]     org.openrewrite.java.migrate.Java8toJava11
[WARNING]         org.openrewrite.java.migrate.javax.AddJaxbDependencies
[WARNING]             org.openrewrite.java.dependencies.AddDependency: {groupId=jakarta.xml.bind, artifactId=jakarta.xml.bind-api, version=2.3.x, onlyIfUsing=javax.xml.bind..*, acceptTransitive=true}
[WARNING]                 org.openrewrite.maven.AddDependency: {groupId=jakarta.xml.bind, artifactId=jakarta.xml.bind-api, version=2.3.x, onlyIfUsing=javax.xml.bind..*, acceptTransitive=true}
[WARNING]             org.openrewrite.java.migrate.javax.AddJaxbRuntime: {runtime=glassfish}
[WARNING]                 org.openrewrite.java.migrate.javax.AddJaxbRuntime$AddJaxbRuntimeMaven
[WARNING]         org.openrewrite.java.migrate.cobertura.RemoveCoberturaMavenPlugin
[WARNING]             org.openrewrite.maven.RemovePlugin: {groupId=org.codehaus.mojo, artifactId=cobertura-maven-plugin}
[WARNING]         org.openrewrite.java.migrate.wro4j.UpgradeWro4jMavenPluginVersion
[WARNING]             org.openrewrite.maven.UpgradePluginVersion: {groupId=ro.isdc.wro4j, artifactId=wro4j-maven-plugin, newVersion=1.10.1}
[WARNING]         org.openrewrite.java.migrate.JavaVersion11
[WARNING]             org.openrewrite.java.migrate.UpgradeJavaVersion: {version=11}

The Java8toJava11 recipe produces the following main relevant changes:

-    <java.version>1.8</java.version>
+    <java.version>11</java.version>

-    <wro4j.version>1.8.0</wro4j.version>
+    <wro4j.version>1.10.1</wro4j.version>

+    <dependency>
+      <groupId>jakarta.xml.bind</groupId>
+      <artifactId>jakarta.xml.bind-api</artifactId>
+      <version>2.3.3</version>
+    </dependency>

+    <dependency>
+      <groupId>org.glassfish.jaxb</groupId>
+      <artifactId>jaxb-runtime</artifactId>
+      <version>2.3.8</version>
+      <scope>provided</scope>
+    </dependency>

Here, we see that the java.version Maven property is changed to 11, which sets maven.compiler.source and maven.compiler.target. This unlocks Java 11 language features such as var. Along the way, wro4j is updated to their latest version as well. Wro4j is a popular open-source project for optimizing and managing web resources in Java applications, such as JavaScript and CSS files. In addition, when migrating from Java 8 to Java 11, one of the major changes is the removal of the javax.xml.bind module from the JDK. Many applications that rely on this module for JAXB functionality need to add third-party dependencies to retain this functionality. One such replacement is the jakarta.xml.bind-api dependency.

6. Conclusion

In this tutorial, we have provided a step-by-step guide on leveraging the OpenRewrite project to seamlessly upgrade versions of Spring Boot, JUnit, and Java within the Spring PetClinic codebase.

By following this tutorial, we can gain insights into the intricacies of the upgrade process, ensuring smoother transitions and better code compatibility for these core components.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Course – LS – NPI (cat=Java)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)