首页 > 解决方案 > 将类路径中缺少的注释附加到类时的行为规范

问题描述

我正在寻找一个规范,说明当 Java 类使用消费者类路径中不存在的注释进行注释时的行为规范。具体来说,当带注释的类被打包为 jar 并拉入另一个项目时(在 Maven 术语中,“可选”或“提供”依赖项包含注释并且依赖项选择不依赖它)。

我发现了一个旧的 Eclipse 错误线程,其中提到了这一点:https ://bugs.eclipse.org/bugs/show_bug.cgi?id=320965

我的理解是,如果注释类不存在,则应该从类文件中删除注释。

我观察到了同样的行为;也就是说,当找不到注释时,该类似乎可以正常加载,但我在任何地方都找不到指定的。我正在使用 OpenJDK。

(对于那些好奇的人来说,上下文是使库依赖注入友好而不将其绑定到特定的 DI 框架,所以我想同时使用 CDI 注释和 Guice 注释,但消费者可能不想引入两组注释,如果有的话)

标签: javaannotations

解决方案


Java 语言规范和 Java 虚拟机规范都没有直接涵盖这一点。后者没有讨论用于验证或链接的注释,因此有人可能会争辩说缺少注释类型不应导致类加载失败。JDK API 文档没有讨论这一点,除了在类值注释中缺少类。这看起来像是一个遗漏。

用户定义(非 VM)注释的解析器位于sun.reflect.annotation.AnnotationParser. 如您所见,未知注释被简单地跳过:

try {
    try {
        sig = constPool.getUTF8At(typeIndex);
        annotationClass = (Class<? extends Annotation>)parseSig(sig, container);
    } catch (IllegalArgumentException ex) {
        // support obsolete early jsr175 format class files
        annotationClass = (Class<? extends Annotation>)constPool.getClassAt(typeIndex);
    }
} catch (NoClassDefFoundError e) {
    if (exceptionOnMissingAnnotationClass)
        // note: at this point sig is "[unknown]" or VM-style
        // name instead of a binary name
        throw new TypeNotPresentException(sig, e);
    skipAnnotation(buf, false);
    return null;
}

也没有办法检测到这种情况发生。因此,如果要确保不存在未知注释,则必须使用不同的解析器解析类文件。


推荐阅读