[英]Loading class with interface from another class loader
我有一个 class Foo
实现了IDoMagic
接口。 Foo
class 由系统类加载器加载, IDoMagic
接口在第三方组件中定义,我认为它在另一个 class 加载器(动态类加载器)中加载接口。
当我尝试创建Foo
的新实例时,我得到了IDoMagic
的NoClassDefFound
。 我认为这是因为它是由不同的 class 加载器加载的。
我试图创建一个BridgeClassLoader
(类似于 Guice 使用的),然后从系统 class 加载器加载 class Foo
,并从我认为是用于IDoMagic
的不同类加载器加载所有其他类,但没有任何成功。
有办法解决吗?
Java中的类加载器(CL)采用委托策略,这意味着该类加载器首先会询问其父母,父母也会询问她的父母是否知道X类的定义。仅当该父母,任何祖先或当前祖父母都没有时classloader知道X的classdefinition,然后当前的classloader将从相应的X.class
文件中加载定义。
如果一个类Foo
是由系统加载器加载的,任何类Foo
是需要dependend也由系统或者CL或CL此的父加载。 由于IDoMagic
是在其他JAR中提供的,因此您很可能需要将此JAR文件添加到类路径( java -cp ...
或java -jar ...
)。 由于委托模型的原因,任何作为此CL子级(以此类推)的CL都将获得对任何父级CL加载的类定义的访问权限。
如果IDoMagic
需要由自定义CL加载,则Foo
一定不能由系统CL加载,而是使用自定义CL或该CL的子IDoMagic
加载,以便启动代理策略并为Foo
提供IDoMagic
的定义。加载/实例化。
有一个自定义的委托CL模型,其中共享类保存在一种通用的CL列表/数组中,供依赖项CL使用。 受抚养人类别不是公共CL的直接子级,而是委托CL的子级,委托CL只是在询问父级是否没有子级能够执行任务之前将调用委托给公共CL。 这里的一个解决方案可能是这样的结构:
bootstrap CL
- system CL
- delegation CL
- common CL
- plugin CL
- plugin 1 CL
- plugin 2 CL
在这里,委托CL需要将loadClass(...)
和findClass(...)
的调用委托给它包含的公共CL(对象组成),并且只有在找不到定义的情况下才将调用委托给其父对象。 类似于此仍处于实验阶段的课程
这个委托加载器使IDoMagic
可以使用公共CL fe来加载,而Foo
类可以使用其中一个插件加载器来加载,这不是common CL
的直接子代。 但是,这要求delegation CL
在询问父级之前首先将所有呼叫置入公共CL。 同样,此委托加载器给表增加了一些开销,因为这使定制CL的优势之一(未使用类的卸载)更加困难。
如果 class 加载程序收到 class 加载请求,它不会自行加载
而是将请求委托给parent class的loader,如果parent class loader还有自己的parent class loader,则进一步请求
请求最终会到达顶层启动class加载器,如果父class加载器能够完成class加载任务,则成功返回
如果父加载器无法完成加载任务,子加载器将尝试自行加载。 这是双亲代表团model。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.