Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalArgumentException when parsing a file #4488

Closed
uhafner opened this issue Sep 12, 2024 · 14 comments
Closed

IllegalArgumentException when parsing a file #4488

uhafner opened this issue Sep 12, 2024 · 14 comments
Labels
bug Something isn't working

Comments

@uhafner
Copy link

uhafner commented Sep 12, 2024

What version of OpenRewrite are you using?

I am using

  • <rewrite-maven-plugin.version>5.39.2</rewrite-maven-plugin.version>
  • <rewrite-testing-frameworks.version>2.17.1</rewrite-testing-frameworks.version>
  • <rewrite-static-analysis.version>1.15.0</rewrite-static-analysis.version>
  • <rewrite-migrate-java.version>2.23.0</rewrite-migrate-java.version>
  • <rewrite-recommendations.version>1.8.4</rewrite-recommendations.version>

How are you running OpenRewrite?

I am using the Maven plugin, and my project is a single module project. I did run the command mvn -X clean rewrite:run.

See https://github.com/uhafner/codingstyle for details. The OpenRewrite configuration is visible in the pom.xml.

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

package edu.hm.hafner.util;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.ProtectionDomain;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;

class ResourceExtractorTest {
    void error() {
        ProtectionDomain protectionDomain = mock(ProtectionDomain.class);

        assertThatIllegalArgumentException()
                .isThrownBy(() -> new ResourceExtractor(ResourceExtractor.class, protectionDomain))
                .withMessageContainingAll("CodeSource for", "ResourceExtractor");
    }

    private String readToString(final Path output) {
        try {
            return new String(Files.readAllBytes(output), StandardCharsets.UTF_8);
        }
        catch (IOException exception) {
            throw new UncheckedIOException(exception);
        }
    }
}

What did you expect to see?

No exception.

What did you see instead?

Exception, see stacktrace below.

What is the full stack trace of any errors you encountered?

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.39.2:dryRun (default-cli) on project codingstyle: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.39.2:dryRun failed: Error while visiting src/test/java/edu/hm/hafner/util/ResourceExtractorTest.java: java.lang.IllegalArgumentException: Could not parse as Java
  org.openrewrite.java.internal.template.JavaTemplateParser.lambda$compileTemplate$13(JavaTemplateParser.java:264)
  java.base/java.util.Optional.orElseThrow(Optional.java:403)
  org.openrewrite.java.internal.template.JavaTemplateParser.compileTemplate(JavaTemplateParser.java:264)
  org.openrewrite.java.internal.template.JavaTemplateParser.lambda$parseBlockStatements$9(JavaTemplateParser.java:176)
  org.openrewrite.java.internal.template.JavaTemplateParser.cacheIfContextFree(JavaTemplateParser.java:290)
  org.openrewrite.java.internal.template.JavaTemplateParser.parseBlockStatements(JavaTemplateParser.java:171)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.maybeReplaceStatement(JavaTemplateJavaExtension.java:451)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:445)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:55)
  org.openrewrite.java.JavaVisitor.visitVariableDeclarations(JavaVisitor.java:936)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitVariableDeclarations(JavaTemplateJavaExtension.java:501)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitVariableDeclarations(JavaTemplateJavaExtension.java:55)
  org.openrewrite.java.tree.J$VariableDeclarations.acceptJava(J.java:5785)
  org.openrewrite.java.tree.J.accept(J.java:59)
  org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
  org.openrewrite.TreeVisitor.visit(TreeVisitor.java:147)
  ...
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:333)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
    at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
    at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
    at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
    at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
    at java.lang.reflect.Method.invoke (Method.java:580)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:361)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)

Are you interested in [contributing a fix to OpenRewrite]

Not right now.

@uhafner uhafner added the bug Something isn't working label Sep 12, 2024
@mccartney
Copy link
Contributor

Three observations:

  1. The code given in the snippet above is not self-contained, it has references to other classes. So there's more to the story.
  2. I've just tried the current main of https://github.com/uhafner/codingstyle (1753a19fb613aa147a8134db9ffe8b32f25f95ff), ran mvn -X clean rewrite:run and it passed.
  3. I also tried another commit (8826fcc351959f67906fe42bfb9e75f089d77a0f) mentioned in the description above, and also the mvn -X clean rewrite:run passed.

Thus I think we need more details/context in order to proceed with this bug.

@uhafner
Copy link
Author

uhafner commented Oct 30, 2024

I excluded those files from the analysis, that make problems. Did you remove the exclusion? When I remove the exclusions I get the StackOverFlowException for AbstractComparableTest.java:

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.43.1:run (default-cli) on project codingstyle: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.43.1:run failed: Error while visiting src/test/java/edu/hm/hafner/util/AbstractComparableTest.java: java.lang.StackOverflowError: null
[ERROR]   java.base/java.lang.StringBuilder.<init>(StringBuilder.java:106)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:691)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:682)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:703)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:682)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:703)
[ERROR]   org.openrewrite.java.tree.TypeUtils.toString(TypeUtils.java:682)

and the IAE for ResourceExtractorTest.java:

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.43.1:run (default-cli) on project codingstyle: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.43.1:run failed: Error while visiting src/test/java/edu/hm/hafner/util/ResourceExtractorTest.java: java.lang.IllegalArgumentException: Could not parse as Java
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$compileTemplate$13(JavaTemplateParser.java:264)
[ERROR]   java.base/java.util.Optional.orElseThrow(Optional.java:403)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.compileTemplate(JavaTemplateParser.java:264)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$parseBlockStatements$9(JavaTemplateParser.java:176)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.cacheIfContextFree(JavaTemplateParser.java:290)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.parseBlockStatements(JavaTemplateParser.java:171)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.maybeReplaceStatement(JavaTemplateJavaExtension.java:451)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:445)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:55)

@uhafner
Copy link
Author

uhafner commented Oct 30, 2024

I can try to create a self-contained example from the code above.

@mccartney
Copy link
Contributor

Did you remove the exclusion?

I did not. That was my mistake. Makes sense now.

@knutwannheden
Copy link
Contributor

Using the latest releases of rewrite-java and rewrite-migrate-java the exceptions can no longer be reproduced. Thanks for reporting, @uhafner !

@uhafner
Copy link
Author

uhafner commented Nov 2, 2024

Thanks for fixing this! I can confirm that the IAE is not thrown anymore. I still get the StackOverflowException for AbstractComparableTest.java, but maybe this is a problem with my configuration of the snapshots repositories. I'll retry when the release is available and will reopen #4487 if required.

@uhafner
Copy link
Author

uhafner commented Nov 12, 2024

It looks like the bug appears again. I isolated the problem in uhafner/codingstyle#1227, see maven output of https://github.com/uhafner/codingstyle/actions/runs/11794757482/job/32853026811?pr=1227

I'll try to create a test case but I am still struggling with the required imports that are not available in the unit test...

@uhafner
Copy link
Author

uhafner commented Nov 12, 2024

@mccartney @knutwannheden I'm not sure if you follow closed issues but GitHub does not support reopening tickets.

I still have the problem from above with in my codingstyle project. I exposed a build in a PR that shows the problem: https://github.com/uhafner/codingstyle/actions/runs/11798330588/job/32864251636?pr=1227

I tried to add a test in rewrite but I am struggling with your tooling. The following test succeeds (as test and when the file is used as real example in my project).

    @Test
    void selfReferencingType() {
        rewriteRun(
          java(
            """
package edu.hm.hafner.util;

public abstract class ACTest<T extends Comparable<T>> {
    void shouldBeNegativeIfThisIsSmaller() {
        T smaller = createSmallerSut();
        T greater = createGreaterSut();
    }

    protected abstract T createSmallerSut();

    protected abstract T createGreaterSut();
}
              """
          )
        );
    }

When I add the JavaDoc comments then the test cannot be started:

    @Test
    void selfReferencingType() {
        rewriteRun(
          java(
            """
package edu.hm.hafner.util;

public abstract class ACTest<T extends Comparable<T>> {
    void shouldBeNegativeIfThisIsSmaller() {
        T smaller = createSmallerSut();
        T greater = createGreaterSut();
    }

    /**
     * Creates a subject under test. The SUT must be smaller than the SUT of the opposite method {@link
     * #createGreaterSut()}.
     *
     * @return the SUT
     */
    protected abstract T createSmallerSut();

    /**
     * Creates a subject under test. The SUT must be greater than the SUT of the opposite method {@link
     * #createSmallerSut()}.
     *
     * @return the SUT
     */
    protected abstract T createGreaterSut();
}
              """
          )
        );
    }

What am I doing wrong? I get in my IDE:

LST contains missing or invalid type information
MethodInvocation->Reference->Link->DocComment->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/*~~(MethodInvocation type is missing or malformed)~~>*/.createGreaterSut()

MethodInvocation->Reference->Link->DocComment->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/*~~(MethodInvocation type is missing or malformed)~~>*/.createSmallerSut()
https://docs.openrewrite.org/reference/faq#im-seeing-lst-contains-missing-or-invalid-type-information-in-my-recipe-unit-tests-how-to-resolve
java.lang.IllegalStateException: LST contains missing or invalid type information
MethodInvocation->Reference->Link->DocComment->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/*~~(MethodInvocation type is missing or malformed)~~>*/.createGreaterSut()

MethodInvocation->Reference->Link->DocComment->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/*~~(MethodInvocation type is missing or malformed)~~>*/.createSmallerSut()
https://docs.openrewrite.org/reference/faq#im-seeing-lst-contains-missing-or-invalid-type-information-in-my-recipe-unit-tests-how-to-resolve
	at org.openrewrite.java.Assertions.assertValidTypes(Assertions.java:92)
	at org.openrewrite.java.Assertions.validateTypes(Assertions.java:60)
	at org.openrewrite.java.Assertions$$Lambda$459/0x0000000800221c20.accept(Unknown Source)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:303)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:132)
	at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:127)
	at org.openrewrite.java.JavaTemplateTest.selfReferencingType(JavaTemplateTest.java:191)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

The problematic part of the exception in rewrite-java seems to be the JavaDoc that references the link to the methods. If I remove the links, then everything is green. This seems to be the actual problem behind the exception:

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.44.0:run (default-cli) on project codingstyle: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.44.0:run failed: Error while visiting src/test/java/edu/hm/hafner/util/ACTest.java: java.lang.IllegalArgumentException: Could not parse as Java
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$compileTemplate$13(JavaTemplateParser.java:264)
[ERROR]   java.base/java.util.Optional.orElseThrow(Optional.java:403)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.compileTemplate(JavaTemplateParser.java:264)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$parseBlockStatements$9(JavaTemplateParser.java:176)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.cacheIfContextFree(JavaTemplateParser.java:290)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.parseBlockStatements(JavaTemplateParser.java:171)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.maybeReplaceStatement(JavaTemplateJavaExtension.java:451)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:445)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:55)
[ERROR]   org.openrewrite.java.JavaVisitor.visitVariableDeclarations(JavaVisitor.java:940)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitVariableDeclarations(JavaTemplateJavaExtension.java:501)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitVariableDeclarations(JavaTemplateJavaExtension.java:55)
[ERROR]   org.openrewrite.java.tree.J$VariableDeclarations.acceptJava(J.java:57[90](https://github.com/uhafner/codingstyle/actions/runs/11794811832/job/32853194800?pr=1228#step:5:91))
[ERROR]   org.openrewrite.java.tree.J.accept(J.java:59)
[ERROR]   org.openrewrite.TreeVisitor.visit(TreeVisitor.java:250)
[ERROR]   org.openrewrite.TreeVisitor.visit(TreeVisitor.java:157)
[ERROR]   ...

@knutwannheden knutwannheden reopened this Nov 12, 2024
@knutwannheden
Copy link
Contributor

@uhafner Thanks Ulli. We will take another look.

@uhafner
Copy link
Author

uhafner commented Nov 19, 2024

I'm not sure which version upgrade fixed the problem, but with

    <rewrite-maven-plugin.version>5.45.0</rewrite-maven-plugin.version>
    <rewrite-testing-frameworks.version>2.22.0</rewrite-testing-frameworks.version>
    <rewrite-static-analysis.version>1.20.0</rewrite-static-analysis.version>
    <rewrite-migrate-java.version>2.29.0</rewrite-migrate-java.version>
    <rewrite-recommendations.version>1.13.0</rewrite-recommendations.version>

the exception cannot be reproduced anymore,

see: https://github.com/uhafner/codingstyle/actions/runs/11911694185/job/33193741872?pr=1227

@uhafner uhafner closed this as completed Nov 19, 2024
@timtebeek
Copy link
Contributor

Great to hear, and thanks for coming back to close the issue. Do note that we also offer a rewrite-recipe-bom, which would reduce the versions you need to maintain to just the bom version and plugin version, both updated in sync every two weeks.

@uhafner
Copy link
Author

uhafner commented Nov 19, 2024

Do note that we also offer a rewrite-recipe-bom, which would reduce the versions you need to maintain to just the bom version and plugin version, both updated in sync every two weeks.

Thanks, I wasn't aware of that. But it looks that this does not yet work in Maven for build plugins (it does work for project dependencies). In your documentation I also found the caveat:

Maven does not currently support using a bill of materials (BOM) to specify plugin versions or dependencies. This means that you will have to specify the versions of each plugin by hand, unlike in the Gradle section below.

@timtebeek
Copy link
Contributor

Ah of course yes; I hadn't looked at your project yet but we often see folks develop their own recipe library, specify bom managed transitive dependency versions there, and then only depend on their own recipe library in their plugin configuration. I now see your setup is different and indeed would need to be more explicit about versions for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

4 participants