openrewrite / openrewrite/rewrite

ChangePackage recipe does not handle package names with single element

Open
#4,142 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
3.7k
Forks
570
Avg merge
13h 12m
Merged PRs (30d)
261

Description

What version of OpenRewrite are you using?

I am using

  • OpenRewrite v8.23.3
  • Maven/Gradle plugin gradlew

How are you running OpenRewrite?

Initially observed the issue when running in a custom Bazel setup but reproduced on an OpenRewrite fork off the main branch with a new test.

Fork
Example Test

What is the smallest, simplest way to reproduce the problem?

./gradlew -q :rewrite-java-test:test --tests org.openrewrite.java.ChangePackageBugTest

> Configure project :
Inferred project: rewrite, version: 0.1.0-SNAPSHOT

> Task :rewrite-java-test:test FAILED

ChangePackageBugTest > updateVariableType() FAILED
    org.opentest4j.AssertionFailedError: [Unexpected result in "A.java":
    diff --git a/A.java b/A.java
    index 4f96f86..ef55fc0 100644
    --- a/A.java
    +++ b/A.java
    @@ -1,4 +1,4 @@ 
    -import org.openrewrite.somepkg.Test;
    +import somepkg.Test;
 
     public class A {
         Test a;
    ] 
    expected: 
      "import org.openrewrite.somepkg.Test;
  
      public class A {
          Test a;
      }"
     but was: 
      "import somepkg.Test;
  
      public class A {
          Test a;
      }"
        at java.base@17.0.4.1/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base@17.0.4.1/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base@17.0.4.1/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base@17.0.4.1/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at app//org.openrewrite.test.RewriteTest.assertContentEquals(RewriteTest.java:617)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:508)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:133)
        at app//org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:128)
        at app//org.openrewrite.java.ChangePackageBugTest.updateVariableType(ChangePackageBugTest.java:73)

ChangePackageBugTest > renameImport() FAILED
    java.lang.AssertionError: Recipe was expected to make a change but made no changes.
        at org.openrewrite.test.LargeSourceSetCheckingExpectedCycles.afterCycle(LargeSourceSetCheckingExpectedCycles.java:118)
        at org.openrewrite.RecipeScheduler.runRecipeCycles(RecipeScheduler.java:97)
        at org.openrewrite.RecipeScheduler.scheduleRun(RecipeScheduler.java:41)
        at org.openrewrite.Recipe.run(Recipe.java:340)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:375)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:133)
        at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:128)
        at org.openrewrite.java.ChangePackageBugTest.renameImport(ChangePackageBugTest.java:48)

3 tests completed, 2 failed

The test itself attempts to change a package from somepkg to org.openrewrite.somepkg but imports are not updated.

The issue stems from visitFieldAccess in the ChangePackage recipe which invokes isFullyQualifiedClassReference on the FieldAccess, passing in the old package name. This method expects there to be a . in the value passed in. It's not clear to me what the fix is since isFullyQualifiedClassReference is expecting a class reference, not a package name.

Are you interested in [contributing a fix to OpenRewrite

Sure, once I'm more comfortable with the codebase.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with rewrite-java/src/main/java/org/openrewrite/java/ChangePackage.java, especially visitFieldAccess, and inspect isFullyQualifiedClassReference in rewrite-java/src/main/java/org/openrewrite/java/tree/J.java. Run the referenced ChangePackageBugTest.java test class; done means package changes with single-element names update imports and the regression tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.