我正在编写Eclipse插件来支持 弗莱格 编程语言。我用 小鬼 元工具平台和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.prelude.Base 上面提到的类是每个模块都需要的基本库,因此它必须在激活插件时加载,尽管当然还有其他类加载程序。

有人有类似的经历吗?可以解决这个问题吗?欢迎任何建议如何规避这一点。

有帮助吗?

解决方案

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top