Skip to content

Conversation

@Pankraz76
Copy link

@Pankraz76 Pankraz76 commented Jul 28, 2025

#17487

Add rewrite support for errorprone.refasterrules

I’d like to propose integrating Google’s Error Prone and its Picnic extension (demonstrated in Automating Away Bugs with Error Prone | PlatformCon 2023) to enable automated bug fixes via rewrite rules. This would complement Checkstyle’s static analysis capabilities by addressing semantic bugs rather than stylistic issues.

Motivation

Error Prone’s refaster/rewrite rules can automatically:

  • Fix common bug patterns (e.g., String.equals() misuse)
  • Modernize code (e.g., JDK migration helpers)
  • Enforce best practices (e.g., null-check improvements)

Real-world adoptions show tangible benefits:

Proposal

  1. Add support for errorprone.refasterrules-based rewrites
  2. Implement with opt-in adoption (no breaking changes)
  3. Include suppression mechanisms for API constraints

Discussion Points

  • Need consensus on:
    • Scope of auto-fixes
    • Preferred suppression strategy
    • Integration approach

Next Steps

I’m happy to:

  • Prepare a PoC demonstrating the value
  • Collaborate on implementation strategy
  • Address any concerns about compatibility

@Pankraz76

This comment was marked as resolved.

@Pankraz76 Pankraz76 force-pushed the openrewrite branch 9 times, most recently from 2aca6b4 to e6e7b4a Compare July 28, 2025 21:58
@Pankraz76

This comment was marked as resolved.

@Pankraz76 Pankraz76 force-pushed the openrewrite branch 3 times, most recently from af8fb66 to 78b6650 Compare July 29, 2025 09:28
@Pankraz76 Pankraz76 changed the title Proposal: Add rewrite support for errorprone.refasterrules Add rewrite support for errorprone.refasterrules Jul 29, 2025
@Pankraz76 Pankraz76 force-pushed the openrewrite branch 4 times, most recently from 6f91533 to bf4d80f Compare July 29, 2025 10:21
@Pankraz76

This comment was marked as resolved.

@Pankraz76 Pankraz76 force-pushed the openrewrite branch 4 times, most recently from 163e83b to 24d6679 Compare July 29, 2025 11:18
Copy link
Contributor

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been awhile since I looked at checkstyle, so my recollections might be out of date but I think of it as very focused tool for finding code style issues exclusively. Two things I don't think it does and would be surprised to find out it does:

  1. Change the code, at all.
  2. Find non-style issues.

Checkstyle's purpose is to generate warnings about style issues, nothing more.

That is, I don't want it to be spotbugs or pmd or sptoless. These are separate tools and they work better independently. I prefer the unix-like approach of combining lots of small utilities rather than packaging everything into a single all-purpose-tool.

@Pankraz76
Copy link
Author

Pankraz76 commented Aug 4, 2025

Thank you for reaching out.

This focuses on the internal code for the check itself. The changes won’t alter the check’s external behavior—only improve development performance and quality by helping identify and fix bugs/flaws.

I’ve already had to resolved 70 check-related issues manually, when contributing, which is the nature of check, we all know about.
With this rewrite approach, we could automate such fixes, though only for contributions to the checkstyle project itself.

To clarify, this change won’t be exposed in the delivered .jar. Like PMD or Spotbugs, which aren’t bundled in the final artifact ether, these tools are used during the build process (e.g., like the compiler plugin) but aren’t shipped to customers.

Let me know if you have questions or need further details.

Best regards

@Pankraz76 Pankraz76 requested review from elharo and romani August 4, 2025 09:25
@elharo
Copy link
Contributor

elharo commented Aug 4, 2025

Is this only affecting the source code in this repo? Or is it changing the code of projects that use checkstyle? I'd rather not have this tool changing any code. I want it to report problems. I specifically want it to not attempt to fix them.

@Pankraz76
Copy link
Author

Pankraz76 commented Aug 4, 2025

Is this only affecting the source code in this repo? Or is it changing the code of projects that use checkstyle? I'd rather not have this tool changing any code. I want it to report problems. I specifically want it to not attempt to fix them.

Checkstyle's purpose is to generate warnings about style issues, nothing more.

we also not changing PMD or kafka, by using auto correction.

Its just another static code analysis tool, finally going beyond pointing out, but really fixing the issues.

Increasing dev time, reducing styling efforts.

@Pankraz76
Copy link
Author

Pankraz76 commented Aug 4, 2025

Is this only affecting the source code in this repo? Or is it changing the code of projects that use checkstyle? I'd rather not have this tool changing any code. I want it to report problems. I specifically want it to not attempt to fix them.

this would be for some ppl. quite nice, idk if its even possible, unless customers use checkstyle pom as parent.

You asking for this:

But no, don´t worry. Its, likely, not going to happen at all, but (assuming) definitely not through check and/or with this PR.

@Pankraz76 Pankraz76 changed the title Add rewrite support for errorprone.refasterrules Issue #17487: Add rewrite support for errorprone.refasterrules Aug 4, 2025
@Pankraz76
Copy link
Author

Kindly consider dedicated recipe changes.

Some even dont find anything, which is the overall goal of currently approached analysis.

@romani
Copy link
Member

romani commented Aug 5, 2025

Not sure how we end up in this conversation

Checkstyle's purpose is to generate warnings about style issues, nothing more.

Checkstyle is far above just style. But by name we have bunch for style. Overlap with PMD is significant. Other tools les in overlap. We keep modules on whatever users like to validate.
Checkstyle is very moduled , so you activate Checks only that you care and adjust each Check them to your requirements. Very very unix tool like.

I'd rather not have this tool changing any code. I want it to report problems. I specifically want it to not attempt to fix them.

We develop https://github.com/checkstyle/checkstyle-openrewrite-recipes it will help users who want all to be automated. It will be just another tool that user should manually plug in build to do a work.

@Pankraz76
Copy link
Author

Pankraz76 commented Aug 5, 2025

it will help users who want all to be automated

this is already "done" by the cleanup recipe. It can parse the check config and apply accordingly. But its not ready yet. Have not seen it being complain, when applied, once. Maybe due to my mistake or its some kind of bug.

https://docs.openrewrite.org/running-recipes/popular-recipe-guides/automatically-fix-checkstyle-violations

We develop https://github.com/checkstyle/checkstyle-openrewrite-recipes it will help users who want all to be automated. It will be just another tool that user should manually plug in build to do a work.

might be an easy approach for PMD as well.

@adangel
@oowekyala

@Pankraz76 Pankraz76 marked this pull request as draft August 5, 2025 11:04
@romani
Copy link
Member

romani commented Aug 5, 2025

from @Anmol202005:
The issue here is, that when romani executes the build rewrite:dryRun is used which only simulates the changes rather than applying them.
./mvnw -e --no-transfer-progress clean rewrite:dryRun
the above cmd is part of .ci/validation.sh.
Actual execution which will be done by rewrite:run will me much faster.

~/java/github/romani/checkstyle [Pankraz76/openrewrite L|✔] 
$ ./mvnw clean rewrite:run
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 1 modules...
[INFO] Installing Nexus Staging features:
[INFO]   ... total of 1 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] 
[INFO] ------------------< com.puppycrawl.tools:checkstyle >-------------------
[INFO] Building checkstyle 11.0.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- clean:3.5.0:clean (default-clean) @ checkstyle ---
[INFO] Deleting /home/roman/java/github/romani/checkstyle/target
[INFO] 
[INFO] >>> rewrite:6.15.0:run (default-cli) > process-test-classes @ checkstyle >>>
[INFO] 
[INFO] --- tidy:1.4.0:check (validate) @ checkstyle ---
[INFO] 
[INFO] --- enforcer:3.6.1:enforce (enforce-maven) @ checkstyle ---
[INFO] Rule 0: org.apache.maven.enforcer.rules.version.RequireMavenVersion passed
[INFO] 
[INFO] --- enforcer:3.6.1:enforce (enforce-versions) @ checkstyle ---
[INFO] Rule 0: org.apache.maven.enforcer.rules.version.RequireJavaVersion passed
[INFO] Rule 1: org.apache.maven.enforcer.rules.version.RequireMavenVersion passed
[INFO] Rule 2: org.apache.maven.enforcer.rules.dependency.DependencyConvergence passed
[INFO] 
[INFO] --- xml:1.1.0:check-format (default) @ checkstyle ---
[INFO] 
[INFO] --- antlr4:4.13.2:antlr4 (default) @ checkstyle ---
[INFO] ANTLR 4: Processing source directory /home/roman/java/github/romani/checkstyle/src/main/resources
[INFO] Processing grammar: com/puppycrawl/tools/checkstyle/grammar/javadoc/JavadocLexer.g4
[INFO] Processing grammar: com/puppycrawl/tools/checkstyle/grammar/javadoc/JavadocParser.g4
[INFO] Processing grammar: com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageLexer.g4
[INFO] Processing grammar: com/puppycrawl/tools/checkstyle/grammar/java/JavaLanguageParser.g4
[INFO] 
[INFO] --- build-helper:3.6.1:add-source (add-source) @ checkstyle ---
[INFO] Source directory: /home/roman/java/github/romani/checkstyle/target/generated-sources/antlr added.
[INFO] 
[INFO] --- resources:3.3.1:resources (default-resources) @ checkstyle ---
[INFO] Copying 405 resources from src/main/resources to target/classes
[INFO] 
[INFO] --- build-helper:3.6.1:add-test-source (add-test-source) @ checkstyle ---
[INFO] Skipping plugin execution!
[INFO] 
[INFO] --- build-helper:3.6.1:add-test-source (add-it-test-source) @ checkstyle ---
[INFO] Test Source directory: /home/roman/java/github/romani/checkstyle/src/it/java added.
[INFO] 
[INFO] --- build-helper:3.6.1:add-test-source (add-it-test-resource) @ checkstyle ---
[INFO] Skipping plugin execution!
[INFO] 
[INFO] --- build-helper:3.6.1:add-test-source (add-xdocs-examples-source) @ checkstyle ---
[INFO] Test Source directory: /home/roman/java/github/romani/checkstyle/src/xdocs-examples/java added.
[INFO] 
[INFO] --- build-helper:3.6.1:add-test-source (add-xdocs-examples-resource) @ checkstyle ---
[INFO] Skipping plugin execution!
[INFO] 
[INFO] --- compiler:3.14.0:compile (default-compile) @ checkstyle ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 463 source files with javac [debug release 17] to target/classes
[INFO] /home/roman/java/github/romani/checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/DefaultConfiguration.java: Some input files use or override a deprecated API.
[INFO] /home/roman/java/github/romani/checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/DefaultConfiguration.java: Recompile with -Xlint:deprecation for details.
[INFO] /home/roman/java/github/romani/checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.java: /home/roman/java/github/romani/checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.java uses unchecked or unsafe operations.
[INFO] /home/roman/java/github/romani/checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.java: Recompile with -Xlint:unchecked for details.
[INFO] 
[INFO] --- plexus-component-metadata:2.2.0:generate-metadata (default) @ checkstyle ---
[INFO] Discovered 8 component descriptor(s)
[INFO] 
[INFO] --- exec:3.5.1:java (default) @ checkstyle ---
[INFO] 
[INFO] --- resources:3.3.1:testResources (default-testResources) @ checkstyle ---
[INFO] Copying 3174 resources from src/test/resources to target/test-classes
[INFO] 
[INFO] --- compiler:3.14.0:testCompile (default-testCompile) @ checkstyle ---
[INFO] Recompiling the module because of changed dependency.
[INFO] Compiling 823 source files with javac [debug release 17] to target/test-classes
[INFO] /home/roman/java/github/romani/checkstyle/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java: Some input files use or override a deprecated API.
[INFO] /home/roman/java/github/romani/checkstyle/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java: Recompile with -Xlint:deprecation for details.
[INFO] /home/roman/java/github/romani/checkstyle/src/test/java/com/puppycrawl/tools/checkstyle/AbstractGuiTestSupport.java: Some input files use unchecked or unsafe operations.
[INFO] /home/roman/java/github/romani/checkstyle/src/test/java/com/puppycrawl/tools/checkstyle/AbstractGuiTestSupport.java: Recompile with -Xlint:unchecked for details.
[INFO] 
[INFO] --- jacoco:0.8.13:instrument (default-instrument) @ checkstyle ---
[INFO] 
[INFO] <<< rewrite:6.15.0:run (default-cli) < process-test-classes @ checkstyle <<<
[INFO] 
[INFO] 
[INFO] --- rewrite:6.15.0:run (default-cli) @ checkstyle ---
[INFO] Using active recipe(s) [org.openrewrite.java.RemoveUnusedImports, org.openrewrite.maven.OrderPomElements, org.openrewrite.maven.cleanup.PrefixlessExpressions, org.openrewrite.staticanalysis.LowercasePackage, org.openrewrite.staticanalysis.MissingOverrideAnnotation, org.openrewrite.staticanalysis.ModifierOrder, org.openrewrite.staticanalysis.RemoveUnusedLocalVariables, org.openrewrite.staticanalysis.RemoveUnusedPrivateFields, org.openrewrite.staticanalysis.RemoveUnusedPrivateMethods, tech.picnic.errorprone.refasterrules.BigDecimalRulesRecipes, tech.picnic.errorprone.refasterrules.BugCheckerRulesRecipes, tech.picnic.errorprone.refasterrules.CharSequenceRulesRecipes, tech.picnic.errorprone.refasterrules.ClassRulesRecipes, tech.picnic.errorprone.refasterrules.ComparatorRulesRecipes, tech.picnic.errorprone.refasterrules.FileRulesRecipes, tech.picnic.errorprone.refasterrules.MicrometerRulesRecipes, tech.picnic.errorprone.refasterrules.OptionalRulesRecipes, tech.picnic.errorprone.refasterrules.PatternRulesRecipes, tech.picnic.errorprone.refasterrules.PreconditionsRulesRecipes, tech.picnic.errorprone.refasterrules.PrimitiveRulesRecipes, tech.picnic.errorprone.refasterrules.StreamRulesRecipes, tech.picnic.errorprone.refasterrules.SuggestedFixRulesRecipes]
[INFO] Using active styles(s) []
line 1:94 missing ')' at '<EOF>'
line 1:88 no viable alternative at input ', String, String'
line 1:88 no viable alternative at input ', String'
line 1:88 missing ')' at '<EOF>'
[INFO] Validating active recipes...
[INFO] Project [checkstyle] Resolving Poms...
[INFO] Project [checkstyle] Parsing source files
[INFO] Running recipe(s)...
[INFO] Printing available datatables to: target/rewrite/datatables/2025-08-05_05-38-35-659
[WARNING] The recipe produced 31 warning(s). Please report this to the recipe author.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:07 min
[INFO] Finished at: 2025-08-05T05:38:35-07:00
[INFO] ------------------------------------------------------------------------

please abandon dryrun, it does not work for us. and use approach I suggested above to just check diff after CI command execution , most CI already have it.

@Pankraz76
Copy link
Author

will me much faster.

considering dedicated test run on CI comparing both, its seems to be quite a similar result as expected, due to the same workload.

./.ci/validation.sh rewriteRun git-diff
33m 39s

./.ci/validation.sh rewriteDryRun
33m 15s

This makes the extra configuration questionable.

Its "just" cosmetics, how you want to handle it is up to you.

dryrun will provide functional output how to fix.

Might want to go (c)lean here consider to convent over config principle.

@Pankraz76
Copy link
Author

closing to stop starting start finishing.

@Pankraz76 Pankraz76 closed this Aug 17, 2025
@Pankraz76
Copy link
Author

That is, I don't want it to be spotbugs or pmd or sptoless

The reality is that Spotless automates code formatting checks, making tools like Checkstyle painless to use. Since it automatically fixes violations, it becomes a seamless part of the development workflow (e.g., in Maven you committed to).

The hesitation is confusing when you compare it to SpotBugs or PMD. The critical difference is that those tools only identify issues—they don't automatically fix them.

Spotless removes the manual effort entirely, which is generally a good thing considering maven parent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants