什么是classloader反转

时间:2011-11-02 03:44:45

标签: java classloader

任何人都可以从“核心java第二卷第8版”第759页解释以下段落:

  

您的应用程序代码包含一个调用的辅助方法   Class.forName(classNameString)

     

从插件类调用该方法。

     

classNameString指定插件中包含的类   罐。

     

插件的作者对该类有合理的期望   应该加载。但是,辅助方法的类是由   系统类加载器,也就是使用的类加载器   Class.forName。插件JAR中的类不可见。这个   这种现象被称为类加载器反转......

根据我的理解,如果“辅助方法的类由系统类加载器加载”,那么它所在的插件jar必须放在CLASSPATH中,并且如果“classNameString指定包含在其中的类”插件JAR“然后这两个类应该都在同一个jar文件中,这是在CLASSPATH中,那么为什么”插件JAR中的类不可见“

2 个答案:

答案 0 :(得分:3)

Say类Helper.class位于core.jar中,它位于CLASSPATH上并由系统类加载器加载。

PluginMain.class和PluginWidget.class在plugin.jar中,但是plugin.jar不在CLASSPATH上。

作为插件系统的一部分,插件创建一个名为PluginClassLoader的新类加载器,使用它从plugin.jar加载PluginMain.class,并调用PluginMain.start()。

如果PluginMain.start()调用Helper.deluxeLoadClass(“PluginWidget.class”),并且deluxeLoadClass()最终调用Class.forName(“PluginWidget.class”),则会发生类加载器反转。这失败了,因为Helper.class是由系统类加载器加载的,它不能看到PluginWidget.class,因为系统类加载器在其类路径上没有plugin.jar。

这个例子有点人为,但这些事情在使用complex class loader hierarchies的J2EE容器中更频繁地发生。

答案 1 :(得分:3)

这是从旧的Halloway书籍Java平台的组件开发(我实际上仍然推荐)中解释的。

应用程序的Main类可以引用java.lang.String,即使Main来自类路径类加载器,String来自引导加载程序。

String但是,不能引用Main,因为类路径加载器不是引导加载程序委派的一部分。 来自父加载器的类无法从子加载器引用类。

这与你的例子是一样的; PluginMain的类加载器可以调用Helper,因为Helper是由父类加载器加载的。但是Helper 无法看到PluginWidget,因为小部件类是由类加载器加载的。