我正在运行我编写的注释处理器。它在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来检测到它。

07-25 22:47