Visit Azul.com Support

Automatically Deprecate Code with the Azul OpenRewrite Plugin

Moderne is a software vendor that helps enterprises to safely refactor, secure, and migrate code across multiple repos and billions of lines of code by leveraging OpenRewrite, which is an open source software auto-refactoring tool (OSS project). The Moderne Platform can use Code Inventory’s data to automatically tag, flag and eventually remove unused and dead code at scale, across multiple repositories.

Thanks to a partnership between Azul and Moderne, OpenRewrite can perform semantic analysis and automated refactoring of code using search and transformation recipes. Such recipes are expert, rules-based programs that enable accurate, automated code changes.

Azul OpenRewrite Plugin

Azul OpenRewrite Plugin is a Maven/Gradle plugin designed to integrate with Azul Code Inventory. Its primary goal is to automatically identify and annotate deprecated code elements within a codebase, based on unused code analysis reports from Azul Intelligence Cloud.

The plugin focuses solely on adding @Deprecated annotations to unused classes. Class removal is left to the customer, as unused classes flagged by Code Inventory may still be referenced elsewhere in the code. Since the resolution of such cases can vary, the plugin avoids making assumptions about how customers prefer to handle them.

Workflow Overview

The plugin iterates over classes listed in the Code Inventory report that match predefined filters.

Logic

The plugin analyzes the report and manages new and existing @Deprecated annotations. If a class has not been used for more than the configured lastSeenAge, an annotation gets added. Also, existing annotations are removed if the class is used again.

All annotations made by your developers will be left untouched.

Workflow

  1. Generate a Code Inventory report using the Intelligence Cloud Web UI or CLI and save it locally. We recommend to generate a report with the parameters use=ALL, a period of 6 months, and an AppEnvs filter. The report must contain data from the same app as the one is being annotated otherwise the plugin will misbehave.

  2. Create a rewrite.yml file (see Configuring the Plugin) and specify which packages and/or classes must be included or excluded. Included ones will be annotated if unused. Excluded ones will be ignored. Take into consideration that excluded has a higher priority than included.

  3. Run the plugin. This will add or remove @Deprecated annotations based on the report. Only the annotation this plugin has added before, will be removed again, no @Deprecated annotations from other sources.

  4. The development team decides which and when deprecated classes get removed from the codebase.

  5. This workflow needs to be repeated to make sure new unused code gets annotated.

Note
How long Code Inventory monitors your applications, as well as the timing of each phase in the process, is controlled by you.

The plugin operates on a "Do no harm" policy, and non-existing classes will be ignored.

Practical Example

Imagine you have an application running with different versions. Through an effective use of the AppEnv parameter in your client settings, you can identify those apps with a prefix. For example, the following AppEnv can exist in your environment for the same application in different versions:

  • my_app_1.24

  • my_app_1.345_test

  • my_app_1.1

In this example, use the CONTAINS my_app filter when generating the report to get the data for all these apps. If the naming scheme in your particular case is more complicated, you can use the AppEnvs parameter in the report which supports full regular expressions.

Please note that if data from multiple different applications is combined under the parameters, the results may be inconsistent.

Annotations

The annotations added by the plugin are slightly different depending on the Java version of the project.

Java 8

 
/** * @deprecated Unused in configured AppEnvs for more than 1 day. code-inventory-2025-09-25 */ @Deprecated public class LegacyService { }

Java 9+

 
@Deprecated(since = "code-inventory-2025-09-18") public class OldController { }

The since value is the finishing time of the report (code-inventory-YYYY-MM-DD).

Integrating the Plugin

Software Requirements

  • JDK 1.8 or higher

  • OpenRewrite Plugin

Downloading the Plugin

  1. Download the latest version of the plugin from:

    • The Azul repository:

       
      curl -O https://cdn.azul.com/openrewrite/openrewrite-0.0.9.zip
    • Or your Intelligence Cloud Web UI.

  2. Unzip the download.

  3. Install it into your local Maven by running the following command:

     
    mvn install:install-file \ -Dfile=azul-openrewrite-0.0.9.jar \ -DpomFile=azul-openrewrite-0.0.9-pom.xml
  4. And/or install it into your company repository and include that repository in your Maven/Gradle build files.

Configuring a Project

You can use the plugin in both Gradle and Maven projects.

Gradle

Configuration for your build.gradle file:

 
plugins { id 'org.openrewrite.rewrite' version '7.18.0' } dependencies { rewrite "com.azul.ic:openrewrite-recipe:0.0.9" } repositories { mavenLocal() } rewrite { activeRecipe('Azul') // This name refers to the `name` used in rewrite.yml configFile = file('rewrite.yml') // Usage section shows how to setup this file }

With this configuration, you can run the plugin using this command:

 
gradle clean build --refresh-dependencies --no-build-cache rewriteRun

Maven

Configuration for your pom.xml file:

 
<project ...> ... <build> <plugins> <plugin> <groupId>org.openrewrite.maven</groupId> <artifactId>rewrite-maven-plugin</artifactId> <version>6.15.0</version> <configuration> <configLocation>rewrite.yml</configLocation> <activeRecipes> <recipe>Azul</recipe> </activeRecipes> </configuration> <dependencies> <dependency> <groupId>com.azul.ic</groupId> <artifactId>openrewrite-recipe</artifactId> <version>0.0.9</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>

With this configuration, you can run the plugin using this command:

 
mvn clean install -U rewrite:run

Configuring the Plugin

All plugin behavior is controlled via the rewrite.yml file which you can adjust to your use-case with the following parameters for the com.azul.openrewrite.UnusedClasses recipe in the recipeList.

Recipe Parameters

Argument Type Description

ciReport

string

Required. Absolute or relative path to the Code Inventory JSON report on local disk.

Example: ./ci-reports/avd-prod-ci.json

appEnvs

string

Required. Comma-separated list of AppEnv regular experssions to filter relevant classes that matches that expression from the report.

Example: appenv1, appenv2

classFilter

string

Required. Packages to include (filters out third-party code).

Example: com.azul.mvr,com.azul.platform,io.acme.product

lastSeenAge

integer

Required. Threshold in days to consider a class unused.

Example: 180

exclude

string

Classes/packages to ignore.

Example: com.azul.utils, com.apache.logger.SomeClass

logLevel

enum

Required. Logging verbosity (error, info, warning, debug, or trace).

maxReportAge

integer

Maximum age of the report before the plugin aborts. When you set this to 0, this check is disabled.

Default value: 30

warnReportAge

integer

Warn if the report is older than this but still valid. When you set this to 0, this check is disabled.

Default value: 7

Recipe Example

 
type: specs.openrewrite.org/v1beta/recipe name: Azul displayName: Mark classes as @Deprecated description: Processes Code Inventory File to find unused classes recipeList: - com.azul.openrewrite.MarkUnusedClasses: ciReport: "./code_inventory_report.json" appEnvs: 'NS_Log4jTest_14_Used_darwin24.0,appenv2,e2e_test_\d' classFilter: org.yourcompany exclude: com.azul.utils, org.yourcompany.utils lastSeenAge: 180 logLevel: warn maxReportAge: 30 warnReportAge: 7