java.lang.Class #getAnnotation()在eclipse插件中调用时返回null

我正在编写一个
eclipse插件来支持
Frege编程语言.

我使用
IMP元工具平台和Eclipse Indigo(3.7).运行时环境是Java 1.7.

该插件使用与批处理编译器相同的代码进行令牌解析,语法分析等.但是,我注意到从eclipse插件运行时的不同行为并将其追溯到以下方法,该方法将先前编译的模块的类文件读取到以java注释的形式获取存储在那里的元信息:

public static MD.Operator[] getOperators(ClassLoader loader, String pack) 
                                              throws ClassNotFoundException {
    Class<?> cl = null;
    cl = loader.loadClass(pack);
    MD.FregePackage os = cl.getAnnotation(MD.FregePackage.class);
    if (os == null) return null;        // <-- no annotation present
    return os.ops();
}    

请注意,代码创建自己的URLClassLoader实例,该实例作为参数传递.如果我没有正确设置类路径,getOperators方法正确抛出ClassNotFoundException,因此我认为我可以确定它加载了类.
跟踪消息告诉我类加载器是使用以下路径构建的(默认情况下它只是类路径):

mkClassLoader:[C:\opt\eclipse\plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar, X:\dev\frege\build]

因为不是由frege编译器创建的类文件通常不能有MD.FregePackage注释,这通常表示用户试图导入普通的java类,实际上我在插件中得到以下消息:

X:/dev/runtime-EclipseApplication/TestJFrege/src/Neu.fr:1: `frege.prelude.Base` is not a frege package

然而,从命令行我可以编译这个就好了.我在此处将此作为证据证明所涉及的注释确实可以从同一位置加载:

X:\dev\frege>java -cp ./build frege.compiler.Main X:/dev/runtimeEclipseApplication/TestJFrege/src/Neu.fr
mkClassLoader: [./build]
running: javac -cp ./build -d . -encoding UTF-8 ./Neu.java

恢复事实:

>当通过命令行界面调用编译器时,应该加载注释的代码可以正常工作.
>应该加载注释的代码不知道是从插件还是命令行调用它.事实上,该插件直到上周才存在,而命令行界面曾经工作好几个月.
>当然,注释具有RetentionPolicy.RUNTIME,否则命令行编译也无法识别它们.但它可以做到.

因此,我可以得出的唯一结论是Class.getAnnotation()不知何故无法正常工作.这非常不幸,因为这有效地破坏了模块系统所需的基本功能.

如果这无关紧要:插件使用的Frege编译器代码本身是用Frege编写的,上面提到的frege.prelude.Base类是每个模块都需要的基本库,因此它必须在激活插件时加载虽然当然有不同的类加载器.

有没有人有类似的经历?是否有可能解决这个问题以及如何解决?如何规避这一点的任何建议都是受欢迎的.

最佳答案 MD.FregePackage类是否由您的方法中使用的类加载器加载?可能首先尝试加载那个,因为如果它们由不同的类加载器加载,则两个类不相等().这可以解释为什么没有找到它.

点赞