Java Application Modernization: Upgrade to Java 17 with Amazon Q Transform and Diffblue Cover for Automated Regression Testing

Estafet consultants occasionally produce short, practical tech notes designed to help the broader software development community and colleagues. 

If you would like to have a more detailed discussion about any of these areas and/or how Estafet can help your organisation and teams with best practices in improving your SDLC, you are very welcome to contact us at enquiries@estafet.com 

Introduction

The objective of this document is to demonstrate a potential approach to modernising and upgrading a legacy Java software codebase from older to newer Java versions (along with dependencies) with the help of two recent powerful AI automation tools, to achieve potentially highly significant cost and time savings. The keyword here is potentially since the upgrade tool itself is still in “preview” and not enterprise ready. We will start by upgrading a Java 8 project, and applying regression tests after.

For this purpose, we will use a project, well known to most developers – OpenAPI Petstore.

The upgrade to Java 17 will be performed with the assistance of Amazon Q Transform, an evolving tool in Amazon Codewhisperer which enables the automated upgrade of a Java 8 codebase to Java 17.

The automated generation of regression unit tests will be done with the assistance of Diffblue Cover.

The overall aim will be to see how these tools might be used to not only update a legacy codebase, but to also significantly improve it using the automated generation of full suite of regression unit tests, resolving weaknesses in the original codebase’s test coverage.

Understanding the project

The above mentioned project is a Spring boot Java 8 application with dynamically generated sources, during build, from a provided OpenAPI spec(resources/openapi.yaml). This document assumes that the reader is already familiar with the structure and has explored the functionality.

Note: if you are having trouble running the project, you might need to add the generated sources as sources root in your IDE, or (recommended) add them as an entry in the POM file:

Preparing for upgrade

Before starting the upgrade process, we must ensure that the project builds and runs. In our case, a “mvn clean package” should produce a similar result:

And a subsequent “mvn spring-boot:run” should start the service.

Let’s confirm it is working by accessing the swagger page: http://localhost:8080/ :

After confirming that the project builds and runs as-is (Java 8) we can stop the server.

Amazon Q Transform

Prerequisites

In this document we assume that the reader is familiar with Amazon Q Transform and the following guidelines in setting up proper account permissions and plugin set up (we will be using VScode):

https://aws.amazon.com/blogs/aws/upgrade-your-java-applications-with-amazon-q-code-transformation-preview/

https://community.aws/content/2Yu3nix1YGNOQ6uxmaaipFceLEa/setting-up-amazon-q-in-vscode-using-iam-identity-centre?lang=en

Note for IntelliJ users: The steps described in this document are mostly performed using IntelliJ, however, currently the AWS IntelliJ plugin has issues with initiating the Transform process. For the transformation part we will open the project in VScode and follow the respective guide to authenticate: https://community.aws/content/2Yu3nix1YGNOQ6uxmaaipFceLEa/setting-up-amazon-q-in-vscode-using-iam-identity-centre?lang=en. Afterwards, the process is similar to the IntelliJ plugin one.

Upgrading to Java 17

  1. Open the project in VScode
  2. Click the AWS plugin icon on the side
  3. Select Transform
  4. Click on the module you want to transform (in our case only 1)
  5. Confirm that you have already run mvn clean install and press Transform
  6. Wait for the process to complete in the newly opened console tab (~5-15 minutes):
  7. Analyze the transformation result diff and decide which changes you would like to include. Note: you might notice errors popping up during the transformation process, if the project builds successfully locally, they can be ignored. This is probably due to the functionality being still in preview and not yet polished.
  8. Press Download Proposed Changes


  9. If you are happy with the diff, press accept on the “proposed changes” window
  10. Close VSCode
  11. Open the project in IntelliJ
  12. Go to project structure and change Java SDK from 1.8 to Java 17
  13. Run mvn clean package
  14. Manually resolve any issues with the build, in our case a small issue with the repositories (will hopefully be handled automatically in the future)


    @Override
    public void deleteAllById(Iterable<? extends String> ids) {
        ids.forEach(this::deleteById);
    }

    Solves the issue for UserRepository and

    @Override
    public void deleteAllById(Iterable<? extends Long> ids) {
        ids.forEach(this::deleteById);
    }

    solves the issue for PetRepository and OrderRepository
  15. Run mvn clean package.
  16. Start the service (mvn spring-boot:run) and observe our java 17 Petstore API!

Results

With the help of Amazon Q transform we were able to upgrade all of our dependencies + transform the code to adapt to changes that have been introduced by the changes in the code we depend on.

It is worth noting, however, that since the tool is still in preview it does not perform nearly as well as we would expect in order for it to be as useful as advertised. We still had to do a manual change that was simple enough to be automated, the plugin ran with errors and also Spring Security changes were not updated properly and needed manual intervention as well.

Diffblue Cover

We managed to upgrade to Java 17 with little to no effort and now it’s time to further improve the resulting codebase with regression tests.

Prerequisites

For instructions on how to set up Diffblue, we have an in depth guide here: https://estafet.com/revolutionising-java-development-exploring-ais-role-in-enhancing-regression-and-end-to-end-testing-alongside-bdd-an-overview-and-analysis-of-emerging-tools-and-techniques/

Adding Regression tests

The idea here is to create a “snapshot” of the working codebase that can be ran whenever a change occurs. After confirming that our upgraded service boots up and works, we can proceed with generating unit regression tests for the whole project.

  1. Open the project in IntelliJ
  2. Right click at the root, or on a specific file and select Write Tests
  3. Asses the recommendations from Diffblue (if any), in our case we have issues to be fixed and Diffblue proposes an autofix option, press that and re-run step 2.
  4. Wait for the test generation to complete (In our case I selected only UserApiDelegateImpl for test generation):
  5. You can find the generated tests in src/test/java

Results

As we can see, with a few clicks we managed to create a snapshot of all the functionality covered by that class, we can verify that the tests are working by executing everything in the generated file.

A total of 193 human readable unit regression tests were created in a blink of an eye!

We can now use these tests as a baseline when implementing future changes, and after confirming that these said changes do not introduce a regression, we can rerun generation to create a newer snapshot

Conclusion

With very little effort we managed to upgrade an outdated Java 8 project to Java 17, and then hardened it with unit regression tests + a health check.

This can greatly improve development performance and open new opportunities for legacy code revival, especially in large codebases – where the impact will be noticeable.

The major issues encountered with Amazon Q Transform, and current workarounds were:

  1. Complex registration and permissions configuration issues accessing the tool
  2. Issues with initial execution of the tool through the respective editor plugins:
    1. IntelliJ plugin: does not work, issue is mentioned here https://repost.aws/questions/QUtqh8fN75TOqZ_w20o7GDuA/help-with-amazon-q-transform-set-up-failures
    2. VSCode plugin: similar issues as with the IntelliJ plugin, during initial execution, however the VSCode plugin continues with the process unlike the IntelliJ one
  3. Issues during the transformation process, the plugin shows unclear errors, still proceeds. Takes a very long time to transform a single code base.
  4. The plugin tells us that it cannot complete a maven build, even though we are able to build locally and the same issue comes up with incredibly simple projects with 0-1 dependencies. The lack of an actual build server-side did not tell the “AI” that the project cannot be built with the suggested changes and we had to do manual work (Upgrading to Java 17, step 14.).
  5. Still needed some manual work (Upgrading to Java 17, step 14.) after the proposed changes, which was simple and should’ve been proposed to us already.

By Antonio Lyubchev, Consultant at Estafet

Stay Informed with Our Newsletter!

Get the latest news, exclusive articles, and updates delivered to your inbox.