Links

Automatically fix Checkstyle violations

Most programmers agree that having consistent formatting across a code base makes it easier to work with. Tools like Checkstyle provide automated enforcement of these policies. But it's never fun to have your workflow interrupted by complaints about formatting. This guide will show you how to configure rewrite to automate the remediation of Checkstyle policy violations.

Example Configuration

How you configure Checkstyle integration depends on whether or not your build also applies a Checkstyle plugin. For Gradle builds this means the built-in plugin named Checkstyle Plugin. For Maven builds this means maven-checkstyle-plugin.

With Checkstyle Plugin

If your build uses either the Gradle or Maven checkstyle plugins, then good news, the OpenRewrite build plugins will detect that and automatically match their configuration. All that remains is to activate the Code cleanup recipe:
Maven
Gradle
pom.xml
<project>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.5.2</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.staticanalysis.CodeCleanup</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-static-analysis</artifactId>
<version>1.0.7</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
</configuration>
</plugin>
</plugins>
</build>
</project>
build.gradle
plugins {
id("java")
id("checkstyle")
id("org.openrewrite.rewrite") version("6.3.8")
}
rewrite {
activeRecipe("org.openrewrite.staticanalysis.CodeCleanup")
}
repositories {
mavenCentral() // rewrite is published to Maven Central
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-static-analysis:1.0.7")
}
At this point, you're ready to fix Checkstyle policy violations by running mvn rewrite:run or gradlew rewriteRun.
OpenRewrite can be configured to use different checkstyle policies than your Checkstyle plugin. Follow the "No Checkstyle Plugin" instructions to override the location of the checkstyle configuration file.

No Checkstyle Plugin

If your build does not use either of the Gradle or Maven Checkstyle plugins, you can still configure the rewrite build plugins to use a checkstyle xml configuration file:
Maven
Gradle
pom.xml
<project>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.5.2</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.staticanalysis.CodeCleanup</recipe>
</activeRecipes>
<checkstyleConfigFile>checkstyle.xml</checkstyleConfigFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-static-analysis</artifactId>
<version>1.0.7</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
build.gradle
plugins {
id("java")
id("org.openrewrite.rewrite") version("6.3.8")
}
rewrite {
activeRecipe("org.openrewrite.staticanalysis.CodeCleanup")
checkstyleConfigFile = file("checkstyle.xml")
}
repositories {
mavenCentral() // rewrite is published to Maven Central
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-static-analysis:1.0.7")
}
At this point, you're ready to fix Checkstyle policy violations by running mvn rewrite:run or gradlew rewriteRun.

Applying Refactors before Checkstyle

Depending on exactly how your build is configured, it might run Checkstyle before OpenRewrite. So the Checkstyle tool might report violations that would be fixed if your build were to run OpenRewrite first.
With this configuration, rewrite refactoring will be run as part of any build that runs checkstyle.

Gradle

In Gradle, Task.dependsOn() can be used to ensure that invoking one task always causes another task to run first. That means making all tasks of type org.gradle.api.plugins.quality.Checkstyle depend on the rewriteRun task provided by the OpenRewrite plugin.
Gradle
build.gradle
plugins {
id("java")
id("checkstyle")
id("org.openrewrite.rewrite") version("6.3.8")
}
rewrite {
activeRecipe("org.openrewrite.staticanalysis.CodeCleanup")
checkstyleConfigFile = file("checkstyle.xml")
}
repositories {
mavenCentral() // rewrite is published to Maven Central
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-static-analysis:1.0.7")
}
// In older versions of gradle, use tasks.get() instead of tasks.named()
def rewriteRunTask = tasks.named("rewriteRun")
// In a kotlin build script, use tasks.withType<Checkstyle>()
tasks.withType(Checkstyle) {
dependsOn(rewriteRunTask)
}

Maven

In Maven, the ordering of goals depends first on which phase of the Build Lifecycle they are declared in, then secondarily by the order in which plugins are declared. This means that the rewrite-maven-plugin should be declared above the maven-checkstyle-plugin in your pom.xml and configured to execute within the same phase as you configure checkstyle to run its "check" goal.
Maven
pom.xml
<project>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.5.2</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.staticanalysis.CodeCleanup</recipe>
</activeRecipes>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-static-analysis</artifactId>
<version>1.0.7</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Known Limitations

We don't have OpenRewrite recipes implemented for all publicly available policies. If you find a checkstyle policy violation you'd like automated, visit the rewrite repository and file an issue.
Checkstyle configuration loading only informs the behavior of recipes, not which recipes are active. Regardless of the presence or non-presence of Checkstyle configuration, OpenRewrite will never apply any refactoring you do not explicitly activate.