classpath 中缺少的注释附加到 class 时的行为规范

Specification of behavior when annotation missing from classpath is attached to a class

我正在寻找当 Java class 使用消费者 class 路径中不存在的注释进行注释时的行为规范。具体来说,当注解的 class 被打包为 jar 并拉入另一个项目时(在 Maven 术语中, 'optional' 或 'provided' 依赖项包含注解并且依赖项选择不依赖那个)。

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

My understanding is that annotations are supposed to be dropped from the class file if the annotation class isn't present.

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

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

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

用于用户定义(非 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;
}

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