I am running an annotation processor that I have wrote. It ran fine on JDK 8 and now I am experiencing a problem on JDK 12.
I have a TypeElement
and I want to retrieve its binary name to pass to Class.forName
.
I use javax.lang.model.util.Elements.getBinaryName(TypeElement)
and it returns a garbage value <any?>$OuterClass.InnerClass
instead of the expected example3.OuterClass$InnerClass
.
I attempted to replace getBinaryName
with TypeElement.getQualifiedName
(even though it would not quite work for an inner class) but it gives me the same garbage result. I have tried searching for this issue but most search engines strip all the special characters and give me useless results.
The TypeElement
was obtained by catching a MirroredTypeException
like so:
try {
exampleAnnotation.value();
throw new IllegalStateException("Expected a MirroredTypeException.");
} catch (MirroredTypeException ex) {
return (TypeElement) types.asElement(ex.getTypeMirror());
}
And here is the definition of ExampleAnnotation
:
package example1;
@Target(PACKAGE)
@Retention(RUNTIME)
@Documented
public @interface ExampleAnnotation {
Class<? extends Derived> value() default Derived.class;
interface Derived<A extends Annotation> extends Base<A> {
String foo();
}
}
And here is the instance of the annotation that the processor is accessing in package-info.java
:
@ExampleAnnotation(OuterClass.InnerClass.class)
package example2;
import example1.ExampleAnnotation;
I have also tried the fully qualified name example3.OuterClass.InnerClass.class
but that also results in garbage: <any?>$example3.OuterClass.InnerClass
.
I doubt it matters but the annotation processors are still marked @SupportedSourceVersion(SourceVersion.RELEASE_8)
and I am running this on Gradle 5.3.1.
I've verified the processorpath contains the jars for packages example1 and example3, including the annotation processors.
I've made no changes to account for the module system so I was thinking maybe that's somehow affecting the code.
Just tried creating a Maven project and am currently unable to reproduce the problem, so there may be an issue with my Gradle configuration, similar to what @Colin Alworth has suggested.
I had recently upgraded to a new version of Gradle and started using the "annotationProcessor" dependencies.
It appears that <any?>$
is prepended to binary/qualified class names (as it appears in the source) if the class isn't on the classpath
(or if it isn't imported, or is spelled wrong). I only had the annotation's jar on the processorpath
.
To alert consumers of my annotation processor of this mistake, I was able to detect it by comparing TypeElement.asType().getKind() == TypeKind.ERROR
immediately after catching the MirroredTypeException
.