gpt4 book ai didi

java - 如何让JavaCompiler使用提供的classLoader来查找类?

转载 作者:行者123 更新时间:2023-11-30 02:51:38 25 4
gpt4 key购买 nike

我正在使用this code来自一篇关于如何在运行时编译和使用 Java 类的旧 IBM 博客文章。代码大多工作得很好(顺便说一句,写得很好),但不幸的是,对我来说,它在我的一个用例中不起作用,其中正在编译的类引用只能由类加载器提供的另一个类提供给 CharSequenceCompiler(来自博客文章),而不是由应用程序类加载器提供。

更具体地说,我传递给 CharSequenceCompiler 的类加载器是一个 OSGi 类加载器。

拥有此 classLoader 的包可以查找并返回一个类,例如 Foo

class Foo { public static String FOO = "F"; }

我知道如果您执行 classLoader.findClass("Foo"); ,这会起作用,因为当我从调试器调用它时,它会起作用。

现在,从我在运行时编译的类中,例如Dynamic,我需要使用Foo...所以我传递了Foo Bundle 的 ClassLoader 到 CharSequenceCompiler,然后要求它编译 Dynamic:

class Dynamic { public static String D = Foo.FOO; }

这会导致以下错误:

error: cannot find symbol
Foo.FOO;
^
symbol: variable Foo

如果 FooCharSequenceCompiler 位于同一个项目中,那么它就可以工作......所以从正确的类加载器加载类显然是一个问题。

我已经调试了这段代码几天(或者晚上,tbh),并且无法找出为什么我提供给编译器的类加载器从来没有被询问过这个类......

要求FileManager列出每个包中的资源,但即使我使用调试器手动添加FileObject到返回的列表中,仍然不行。

由于调试器无法穿透 javac 内部使用的 native 类,因此我无法再在这方面取得进展...是否有人了解编译器的内部知识可以解释发生了什么?

最佳答案

经过长时间的斗争,我终于明白了这一点。

我发现的基于 java.tools API 的内存中 java 编译器的几乎所有实现的问题是,即使它们允许您传入 ClassLoader 来加载您编译的类,classLoader用于加载新类,而不用于获取可在正在编译的 Java 代码中使用的类。

因此,我的用例(如问题中所解释的)无法与 IBM 博客文章中显示的代码(或其他项目,如 OpenHFT Java-Runtime-Compiler )一起使用。

如果您希望由您提供给编译器的 ClassLoader 加载的类(在应用程序 ClassLoader 中不可见)可供正在编译的类使用,你需要两件事。

首先,ClassLoader 类必须是可枚举的。然后,JavaFileManager 可以使用它来正确实现 list() 方法。对于每个包,此方法必须返回 ClassLoader 可以在需要时加载哪些类。

其次,您需要能够从 ClassLoader 资源构建 JavaFileObject,因为这是您必须返回的对象的类型。为此,您需要向 ClassLoader 请求类的字节码流(使用 getResourceAsStream("Class.class")),然后创建一个 JavaFileObjectImpl。基本上,这是伪代码:

fileObject = new JavaFileObjectImpl( pathMinusDotClass, JavaFileObject.Kind.CLASS );
fileObject.openOutputStream()
.write( classLoader.getInputStream( path ) );

现在,编译器将知道它可以从提供的类加载器加载哪些类,并且一切正常。

我在我的 OSGiaaS project 上的真实编译器中实现了这个,尚未发布,但我计划很快发布(写于 2016 年 7 月)...它的 shell 中包含一个 Java 命令,可以运行任意 Java 代码,这就是我需要让它工作的原因。

关于java - 如何让JavaCompiler使用提供的classLoader来查找类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38467876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com