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

标签 java eclipse reflection eclipse-plugin frege

我正在编写一个 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

还原事实:

  1. 当通过命令行界面调用编译器时,应该加载注释的代码工作正常。
  2. 应该加载注释的代码不知道它是从插件还是命令行调用的。事实上,该插件直到上周才出现,而命令行界面过去几个月都可以正常工作。
  3. 注释当然有 RetentionPolicy.RUNTIME 否则命令行编译也不会识别它们。但事实证明确实如此。

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

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

有没有人有类似的经历?是否有可能解决这个问题以及如何解决?欢迎提出任何如何规避这种情况的建议。

最佳答案

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

关于在 eclipse 插件中调用时,java.lang.Class#getAnnotation() 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8309444/

相关文章:

javascript - Eclipse Neon Content Assist 没有针对 JavaScript 的提案

c# - 在运行时加载程序集,Autocad 插件示例

java - 如何在同一面板上创建具有两个不同时间间隔的计时器/ Action 事件的多个动画组件?

java - 将 Gradle 与 native 依赖项一起使用

java - Ajax 不工作 JSF 2.2

Java : Getting the currently executing Method corresponding object

powershell - 脚本中的代码有所不同,具体取决于从另一个脚本或shell调用

java - 无法让我的 DialogFragment 背景透明

c - 在 Eclipse 中将 mpifort 设置为编译器

java - Eclipse 因 LauncherFactory 的 NoClassDefFoundError 导致使用 JUnit 5 未找到测试