Skip to content

Javadoc with a slightly broken {@link} containing a line break makes OpenRewrite fail #804

@pantherdd

Description

@pantherdd

What version of OpenRewrite are you using?

Gradle plugin id("org.openrewrite.rewrite").version("7.15.0")
Rewrite module rewrite("org.openrewrite.recipe:rewrite-testing-frameworks:3.16.0")

How are you running OpenRewrite?

I am using the Gradle plugin, and my project is a single module project.

// build.gradle.kts

plugins {
    java
    id("org.openrewrite.rewrite").version("7.15.0")
}

tasks.wrapper {
    gradleVersion = "8.14.3"
}

dependencies {
    testImplementation("junit:junit:4.13.2")
}

tasks.test {
    useJUnit()
}

dependencies {
    rewrite("org.openrewrite.recipe:rewrite-testing-frameworks:3.16.0")
}

rewrite {
    activeRecipe("org.openrewrite.java.testing.junit5.JUnit4to5Migration")
}

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

package reproduction;

import org.junit.Assert;
import org.junit.Test;

public class ReproductionTest {

    public static void fail(String param1, String param2, String param3) {
        // No-op
    }

    /**
     * Method documentation with a broken link to {@link #fail(String, String,
     * Integer)} (the types in the parameter list don't match).
     */
    @Test
    public void test() {
        Assert.assertEquals(42, Integer.parseInt("2a", 16));
    }
}

What did you expect to see?

A successful execution of rewriteRun (where the test class is migrated to JUnit 5).

What did you see instead?

14:37:33: Executing 'rewriteRun'…

> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :compileTestJava

> Task :rewriteRun
Validating active recipes
Scanning sources in project :
Using active styles []
All sources parsed, running active recipes: org.openrewrite.java.testing.junit5.JUnit4to5Migration

> Task :rewriteRun FAILED

[...]

2 actionable tasks: 2 executed

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':rewriteRun'.
> org.openrewrite.internal.RecipeRunException: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1

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

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':rewriteRun'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:130)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:293)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:128)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
	at org.gradle.api.internal.tasks.execution.ProblemsTaskPathTrackingTaskExecuter.execute(ProblemsTaskPathTrackingTaskExecuter.java:41)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:210)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:85)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:459)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:376)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
Caused by: java.lang.RuntimeException: org.openrewrite.internal.RecipeRunException: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
	at org.openrewrite.gradle.DelegatingProjectParser.unwrapInvocationException(DelegatingProjectParser.java:173)
	at org.openrewrite.gradle.DelegatingProjectParser.run(DelegatingProjectParser.java:115)
	at org.openrewrite.gradle.RewriteRunTask.run(RewriteRunTask.java:36)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
	at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:244)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:30)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:27)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:48)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:229)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:212)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:195)
	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:162)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:210)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:42)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:75)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:50)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:28)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:67)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:37)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:61)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:26)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:69)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:46)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:40)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:29)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:189)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:75)
	at org.gradle.internal.Either$Right.fold(Either.java:175)
	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:62)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:46)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:35)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:75)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:53)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:53)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:35)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:49)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:27)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:71)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:39)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:65)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:36)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:107)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:56)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:64)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:43)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.executeWithNonEmptySources(AbstractSkipEmptyWorkStep.java:125)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:56)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:75)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:41)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.lambda$execute$0(AssignMutableWorkspaceStep.java:35)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:289)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:31)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:22)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:40)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:48)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:35)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:127)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
	at org.gradle.api.internal.tasks.execution.ProblemsTaskPathTrackingTaskExecuter.execute(ProblemsTaskPathTrackingTaskExecuter.java:41)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:210)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:85)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:459)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:376)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
Caused by: org.openrewrite.internal.RecipeRunException: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:281)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitRightPadded(JavadocPrinter.java:536)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitContainer(JavadocPrinter.java:529)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitMethodInvocation(JavadocPrinter.java:386)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitMethodInvocation(JavadocPrinter.java:377)
	at org.openrewrite.java.tree.J$MethodInvocation.acceptJava(J.java:4290)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:154)
	at org.openrewrite.java.JavadocVisitor.javaVisitorVisit(JavadocVisitor.java:38)
	at org.openrewrite.java.JavadocPrinter.visitReference(JavadocPrinter.java:372)
	at org.openrewrite.java.JavadocPrinter.visitReference(JavadocPrinter.java:29)
	at org.openrewrite.java.tree.Javadoc$Reference.acceptJavadoc(Javadoc.java:737)
	at org.openrewrite.java.tree.Javadoc.accept(Javadoc.java:40)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.java.JavadocPrinter.visitLink(JavadocPrinter.java:167)
	at org.openrewrite.java.JavadocPrinter.visitLink(JavadocPrinter.java:29)
	at org.openrewrite.java.tree.Javadoc$Link.acceptJavadoc(Javadoc.java:355)
	at org.openrewrite.java.tree.Javadoc.accept(Javadoc.java:40)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.java.JavadocPrinter.visit(JavadocPrinter.java:363)
	at org.openrewrite.java.JavadocPrinter.visitDocComment(JavadocPrinter.java:71)
	at org.openrewrite.java.JavadocPrinter.visitDocComment(JavadocPrinter.java:29)
	at org.openrewrite.java.tree.Javadoc$DocComment.acceptJavadoc(Javadoc.java:159)
	at org.openrewrite.java.tree.Javadoc.accept(Javadoc.java:40)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:154)
	at org.openrewrite.java.tree.Javadoc$DocComment.printComment(Javadoc.java:164)
	at org.openrewrite.java.JavaPrinter.visitSpace(JavaPrinter.java:69)
	at org.openrewrite.java.JavaPrinter.beforeSyntax(JavaPrinter.java:1259)
	at org.openrewrite.java.JavaPrinter.beforeSyntax(JavaPrinter.java:1248)
	at org.openrewrite.java.JavaPrinter.visitMethodDeclaration(JavaPrinter.java:828)
	at org.openrewrite.java.JavaPrinter.visitMethodDeclaration(JavaPrinter.java:35)
	at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava(J.java:4036)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.java.JavaPrinter.visitStatement(JavaPrinter.java:403)
	at org.openrewrite.java.JavaPrinter.visitStatements(JavaPrinter.java:394)
	at org.openrewrite.java.JavaPrinter.visitBlock(JavaPrinter.java:385)
	at org.openrewrite.java.JavaPrinter.visitBlock(JavaPrinter.java:35)
	at org.openrewrite.java.tree.J$Block.acceptJava(J.java:848)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.java.JavaPrinter.visitClassDeclaration(JavaPrinter.java:558)
	at org.openrewrite.java.JavaPrinter.visitClassDeclaration(JavaPrinter.java:35)
	at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava(J.java:1385)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:291)
	at org.openrewrite.java.JavaPrinter.visitCompilationUnit(JavaPrinter.java:571)
	at org.openrewrite.java.JavaPrinter.visitCompilationUnit(JavaPrinter.java:35)
	at org.openrewrite.java.tree.J$CompilationUnit.acceptJava(J.java:1667)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:154)
	at org.openrewrite.Tree.print(Tree.java:81)
	at org.openrewrite.SourceFile.printAll(SourceFile.java:102)
	at org.openrewrite.Result.diff(Result.java:238)
	at org.openrewrite.gradle.isolated.ResultsContainer.<init>(ResultsContainer.java:60)
	at org.openrewrite.gradle.isolated.DefaultProjectParser.listResults(DefaultProjectParser.java:1462)
	at org.openrewrite.gradle.isolated.DefaultProjectParser.run(DefaultProjectParser.java:439)
	at org.openrewrite.gradle.DelegatingProjectParser.lambda$run$2(DelegatingProjectParser.java:116)
	at org.openrewrite.gradle.DelegatingProjectParser.unwrapInvocationException(DelegatingProjectParser.java:166)
	... 121 more
Caused by: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitSpace(JavadocPrinter.java:493)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.beforeSyntax(JavadocPrinter.java:553)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.beforeSyntax(JavadocPrinter.java:545)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitIdentifier(JavadocPrinter.java:393)
	at org.openrewrite.java.JavadocPrinter$JavadocJavaPrinter.visitIdentifier(JavadocPrinter.java:377)
	at org.openrewrite.java.tree.J$Identifier.acceptJava(J.java:2675)
	at org.openrewrite.java.tree.J.accept(J.java:60)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:245)
	... 183 more

Are you interested in contributing a fix to OpenRewrite?

No, because I don't understand how the failing code is supposed to work. My guess is that the problem is caused by the fact that the JAVADOC_LINE_BREAK* messages are stored on the enclosing Javadoc.DocComment instance, while there is an extra line break within the @link, but... there seem to be other factors at play. For example, if the link has the line break in another place, or I switch the parameter order to a different permutation, the error may simply go away. If the linked method's name is not fail, or the parameter list is valid, it seems to also go away. It's all quite intricate, so it took considerable effort to find a minimal reproduction that I could share. Long story short, the problematic code looks too complex for me to understand in a reasonable amount of time.

Additional notes

It would be awesome if there was a way to somehow ignore Javadoc link errors, while still using validation features such as throwOnParseFailures = true. I need to know when the recipe can't do a correct job because it can't resolve some classes that are used by actual code, but I don't want to be blocked by mere documentation linking errors. Just leave the broken Javadoc links as they were.
Alternatively, it would be great to have a recipe that simply turns broken {@link} and similar tags into {@code} – this would provide a simple solution to such cases, without losing information.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions