Since JDK 22 , the implementation of TypeMirror provides access to annotations for types loaded from bytecode (see JDK-8323094). Type annotations are now visible to javac plugins across compilation boundaries (see JDK-8323093)
Reproducer:
$ git clone https://github.com/perceptron8/checker-framework_JDK-8323094
$ cd checker-framework_JDK-8323094/
JDK 21 compilation:
$ export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64/
$ mvn clean verify
[INFO] BUILD SUCCESS
JDK 25 compilation:
$ export JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64/
$ mvn clean verify
[INFO] BUILD FAILURE
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.14.1:testCompile (default-testCompile) on project checker-framework_JDK-8323094: Compilation failure
[ERROR] error: Unexpected null argument: compareByName(@org.checkerframework.common.aliasing.qual.MaybeAliased, null)
With manual javac call, I was able to get a little bit more:
error: Unexpected null argument: compareByName(@org.checkerframework.common.aliasing.qual.MaybeAliased, null)
; The Checker Framework crashed. Please report the crash. Version: Checker Framework 3.51.1.
Compilation unit: ./src/test/java/MyTest.java
Last visited tree at line 3 column 17:
W.wrap(C.create());
Exception: java.lang.Throwable; java.lang.Throwable
at org.checkerframework.javacutil.BugInCF.<init>(BugInCF.java:38)
at org.checkerframework.javacutil.AnnotationUtils.compareByName(AnnotationUtils.java:157)
at org.checkerframework.javacutil.AnnotationUtils.areSameByName(AnnotationUtils.java:192)
at org.checkerframework.javacutil.AnnotationUtils.getSameByName(AnnotationUtils.java:383)
at org.checkerframework.javacutil.AnnotationUtils.containsSameByName(AnnotationUtils.java:368)
at org.checkerframework.framework.type.AnnotatedTypeMirror.hasExplicitAnnotation(AnnotatedTypeMirror.java:623)
("src/main/java/" and "src/test/java/" are compiled separately; bug appears during the latter - that's why I think it is related to JDK-8323094).
AnnotationTypeMirror.hasExplicitAnnotation(Class<? extends Annotation>) is currently implemented like so:
|
public boolean hasExplicitAnnotation(Class<? extends Annotation> a) { |
|
return AnnotationUtils.containsSameByName(getExplicitAnnotations(), getPrimaryAnnotation(a)); |
|
} |
-
getExplicitAnnotations():
- on JDK 21 returns
[],
- on JDK 22+ returns
[@MaybeAliased, @MaybeLeaked].
-
getPrimaryAnnotation(a)
- returns
null regardless of JDK version.
When collection returned by 1. has no elements, null returned by 2. is harmless. When it has some elements, AnnotationUtils.compareByName is called with a2 being null which leads to BugInCF.
Since JDK 22 , the implementation of
TypeMirrorprovides access to annotations for types loaded from bytecode (see JDK-8323094). Type annotations are now visible tojavacplugins across compilation boundaries (see JDK-8323093)Reproducer:
$ git clone https://github.com/perceptron8/checker-framework_JDK-8323094 $ cd checker-framework_JDK-8323094/JDK 21 compilation:
$ export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64/ $ mvn clean verify [INFO] BUILD SUCCESSJDK 25 compilation:
$ export JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64/ $ mvn clean verify [INFO] BUILD FAILURE [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.14.1:testCompile (default-testCompile) on project checker-framework_JDK-8323094: Compilation failure [ERROR] error: Unexpected null argument: compareByName(@org.checkerframework.common.aliasing.qual.MaybeAliased, null)With manual
javaccall, I was able to get a little bit more:("src/main/java/" and "src/test/java/" are compiled separately; bug appears during the latter - that's why I think it is related to JDK-8323094).
AnnotationTypeMirror.hasExplicitAnnotation(Class<? extends Annotation>)is currently implemented like so:checker-framework/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java
Lines 622 to 624 in f17fd42
getExplicitAnnotations():[],[@MaybeAliased, @MaybeLeaked].getPrimaryAnnotation(a)nullregardless of JDK version.When collection returned by 1. has no elements,
nullreturned by 2. is harmless. When it has some elements,AnnotationUtils.compareByNameis called witha2beingnullwhich leads toBugInCF.