Skip to content

Commit

Permalink
Prevent StackOverflowError in JavaTemplateJavaExtension (#4443)
Browse files Browse the repository at this point in the history
The use of `JavaTypeVisitor` in `JavaTemplateJavaExtension` is what caused the `StackOverflowError`, as the `JavaType` graphs can contain cycles and don't provide any mechanism to guard against that.

While I understand the reason for using a `JavaTypeVisitor` to also correct the references to that type in the graph, it won't fix all references in any case, so it seems a bit futile. Until OpenRewrite provides a mechanism to "globally" update a type attribution, I feel like the best option here is to do what other recipes typically do: Just update the reference at hand.

The other alternative here would be to use the internal method `unsafeSet()`.

- Fixes: #4161

Co-authored-by: Tim te Beek <tim@moderne.io>
  • Loading branch information
knutwannheden and timtebeek authored Aug 25, 2024
1 parent 959838c commit 348e118
Showing 1 changed file with 1 addition and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaTypeVisitor;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.tree.*;
import org.openrewrite.marker.Markers;
Expand Down Expand Up @@ -186,29 +185,7 @@ public J visitClassDeclaration(J.ClassDeclaration classDecl, Integer p) {
c = c.withImplements(ListUtils.concatAll(c.getImplements(), implementings));
}
if (c.getType() != null) {
String fqn = c.getType().getFullyQualifiedName();
c = c.withType(new JavaTypeVisitor<List<JavaType.FullyQualified>>() {
@Override
public JavaType visitClass(JavaType.Class aClass, List<JavaType.FullyQualified> fullyQualifiedTypes) {
JavaType.Class c = (JavaType.Class) super.visitClass(aClass, fullyQualifiedTypes);
if (fqn.equals(c.getFullyQualifiedName())) {
c = c.withInterfaces(ListUtils.concatAll(c.getInterfaces(), fullyQualifiedTypes));
}
return c;
}

@Override
public JavaType.Method visitMethod(JavaType.Method method, List<JavaType.FullyQualified> fullyQualifieds) {
// short-circuiting navigation to methods and variables.
return method;
}

@Override
public JavaType.Variable visitVariable(JavaType.Variable variable, List<JavaType.FullyQualified> fullyQualifieds) {
// short-circuiting navigation to methods and variables.
return variable;
}
}.visitNonNull(c.getType(), implementsTypes));
c = c.withType(((JavaType.Class) c.getType()).withInterfaces(ListUtils.concatAll(c.getType().getInterfaces(), implementsTypes)));
}

//noinspection ConstantConditions
Expand Down

0 comments on commit 348e118

Please sign in to comment.