Skip to content

Commit 3fbb6ea

Browse files
authored
Complete Java 24 compatibility fix by backporting UnknownType workaround (#6740)
This completes the Java 24 compatibility work started in PR #6725 by backporting the isUnknownType() helper method that was removed during the May 2025 simplification (commit 08b08ab). Background: - April 2025: JDK 24 support added with reflection-based workarounds - May 2025: Workarounds removed in "simplification" (commit 08b08ab) - February 2026: DocCommentTable fix backported in PR #6725 - This PR: Backports the missing UnknownType fix Problem: Java 24 removed the Type.UnknownType class from javac internals. Direct instanceof Type.UnknownType checks cause NoClassDefFoundError at runtime on Java 24. Solution: Use reflection to check the class name at runtime instead of compile-time instanceof checks. This allows the code to work on both Java 21-23 (where the class exists) and Java 24+ (where it doesn't). Changes: - ReloadableJava21TypeMapping.java: Added isUnknownType() helper, replaced 3 instanceof checks - ReloadableJava21TypeSignatureBuilder.java: Replaced 2 instanceof checks Testing: Verified on spring-petclinic project with Java 24.0.2. Type attribution works correctly, ChangeType and ChangePackage recipes execute successfully, and migrated code compiles without errors. Fixes: #6644 Related: #6725, commit 08b08ab
1 parent 07d1ffe commit 3fbb6ea

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21TypeMapping.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class ReloadableJava21TypeMapping implements JavaTypeMapping<Tree> {
4646
private final JavaTypeCache typeCache;
4747

4848
public JavaType type(@Nullable Type type) {
49-
if (type == null || type instanceof Type.ErrorType || type instanceof Type.PackageType || type instanceof Type.UnknownType ||
49+
if (type == null || type instanceof Type.ErrorType || type instanceof Type.PackageType || isUnknownType(type) ||
5050
type instanceof NullType) {
5151
return JavaType.Class.Unknown.getInstance();
5252
}
@@ -465,7 +465,7 @@ public JavaType.Primitive primitive(TypeTag tag) {
465465
}
466466

467467
if (selectType == null || selectType instanceof Type.ErrorType || symbol == null || symbol.kind == Kinds.Kind.ERR ||
468-
symbol.type instanceof Type.UnknownType) {
468+
isUnknownType(symbol.type)) {
469469
return null;
470470
}
471471

@@ -530,7 +530,7 @@ public JavaType.Primitive primitive(TypeTag tag) {
530530
exceptionTypes.add(javaType);
531531
}
532532
}
533-
} else if (selectType instanceof Type.UnknownType) {
533+
} else if (isUnknownType(selectType)) {
534534
returnType = JavaType.Unknown.getInstance();
535535
}
536536

@@ -751,4 +751,12 @@ private Object annotationElementValue(Object value) {
751751
}
752752
return JavaType.Unknown.getInstance();
753753
}
754+
755+
/**
756+
* Check for the `UnknownType` which existed up until JDK 22; starting with JDK 23 only the `ErrorType` is used.
757+
* Uses reflection to avoid compile-time dependency on the class, which was removed in JDK 24.
758+
*/
759+
public static boolean isUnknownType(@Nullable Type type) {
760+
return type != null && type.getClass().getName().equals("com.sun.tools.javac.code.Type$UnknownType");
761+
}
754762
}

rewrite-java-21/src/main/java/org/openrewrite/java/isolated/ReloadableJava21TypeSignatureBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Set;
3131
import java.util.StringJoiner;
3232

33+
import static org.openrewrite.java.isolated.ReloadableJava21TypeMapping.isUnknownType;
3334

3435
class ReloadableJava21TypeSignatureBuilder implements JavaTypeSignatureBuilder {
3536
@Nullable
@@ -41,7 +42,7 @@ public String signature(@Nullable Object t) {
4142
}
4243

4344
private String signature(@Nullable Type type) {
44-
if (type == null || type instanceof Type.UnknownType || type instanceof NullType) {
45+
if (type == null || isUnknownType(type) || type instanceof NullType) {
4546
return "{undefined}";
4647
} else if (type instanceof Type.IntersectionClassType) {
4748
return intersectionSignature(type);
@@ -299,7 +300,7 @@ private String methodArgumentSignature(Type selectType) {
299300
return resolvedArgumentTypes.toString();
300301
} else if (selectType instanceof Type.ForAll) {
301302
return methodArgumentSignature(((Type.ForAll) selectType).qtype);
302-
} else if (selectType instanceof Type.JCNoType || selectType instanceof Type.UnknownType) {
303+
} else if (selectType instanceof Type.JCNoType || isUnknownType(selectType)) {
303304
return "{undefined}";
304305
}
305306

0 commit comments

Comments
 (0)