我正在运行我编写的注释处理器。它在JDK 8上运行良好,现在我在JDK 12上遇到问题。
我有一个TypeElement
,我想检索其二进制名称以传递给Class.forName
。
我使用javax.lang.model.util.Elements.getBinaryName(TypeElement)
,它返回一个垃圾值<any?>$OuterClass.InnerClass
而不是预期的example3.OuterClass$InnerClass
。
我试图用getBinaryName
替换TypeElement.getQualifiedName
(即使对于内部类来说不太可行),但是它给了我相同的垃圾结果。我曾尝试搜索此问题,但大多数搜索引擎会删除所有特殊字符,并给我带来无用的结果。
通过捕获TypeElement
来获得MirroredTypeException
,如下所示:
try {
exampleAnnotation.value();
throw new IllegalStateException("Expected a MirroredTypeException.");
} catch (MirroredTypeException ex) {
return (TypeElement) types.asElement(ex.getTypeMirror());
}
这是
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();
}
}
这是处理器正在
package-info.java
中访问的注释的实例:@ExampleAnnotation(OuterClass.InnerClass.class)
package example2;
import example1.ExampleAnnotation;
我也尝试过使用完全限定的名称
example3.OuterClass.InnerClass.class
,但这也会导致垃圾:<any?>$example3.OuterClass.InnerClass
。我怀疑这很重要,但是注释处理器仍然标记为
@SupportedSourceVersion(SourceVersion.RELEASE_8)
,我正在Gradle 5.3.1上运行它。我已经验证了processorpath包含了example1和example3包的jar,其中包括注释处理器。
我没有对模块系统进行任何更改,因此我在想这可能会影响代码。
刚刚尝试创建Maven项目,但目前无法重现该问题,因此我的Gradle配置可能存在问题,类似于@Colin Alworth提出的建议。
最佳答案
我最近已经升级到Gradle的新版本,并开始使用“annotationProcessor”依赖项。
如果该类不在<any?>$
上(或者如果未导入或拼写错误),则classpath
似乎以二进制/限定的类名开头(如在源代码中所显示)。我只有processorpath
上具有注释的jar。
为了提醒消费者我的注释处理器此错误,我能够在捕获TypeElement.asType().getKind() == TypeKind.ERROR
之后立即通过比较MirroredTypeException
来检测到它。