Reputation: 61
Can anybody please explain the following paragraph from "core java volume II 8th edtion" page 759:
Your application code contains a helper method that calls
Class.forName(classNameString)
.That method is called from a plugin class.
The
classNameString
specifies a class that is contained in the plugin JAR.The author of the plugin has the reasonable expectation that the class should be loaded. However, the helper method's class was loaded by the system class loader, and that is the class loader used by
Class.forName
. The classes in the plugin JAR are not visible. This phenomenon is called classloader inversion ...
From my understanding, if "the helper method's class was loaded by the system class loader", then the plugin jar it is in must be placed in the CLASSPATH, and also if "The classNameString specifies a class that is contained in the plugin JAR" then these two classes should be both in the same jar file, which is in CLASSPATH, then why "The classes in the plugin JAR are not visible"
Upvotes: 4
Views: 950
Reputation: 160271
This is paraphrased from the old Halloway book Component Development for the Java Platform (which I actually still recommend).
An application's Main
class can reference java.lang.String
even though Main
comes from the classpath class loader and String
comes the bootstrap loader.
String
, however, cannot refer to Main
, because the classpath loader is not part of the bootstrap loader's delegation. A class from a parent loader cannot reference a class from a child loader.
It's the same thing as your example; PluginMain
's class loader can call Helper
, because Helper
was loaded by a parent class loader. But Helper
cannot see PluginWidget
, because the widget class was loaded by a child class loader.
Upvotes: 5
Reputation: 25150
Say class Helper.class is in core.jar, which is on the CLASSPATH and loaded by the system class loader.
PluginMain.class and PluginWidget.class is in plugin.jar, but plugin.jar is not on the CLASSPATH.
As part of the plugin system, the plugin creates a new class loader called PluginClassLoader, uses it to load PluginMain.class from plugin.jar, and calls PluginMain.start().
Classloader inversion occurs if PluginMain.start() calls Helper.deluxeLoadClass("PluginWidget.class"), and deluxeLoadClass() eventually calls Class.forName("PluginWidget.class"). This fails, because Helper.class was loaded by the system class loader, which can't see PluginWidget.class, as the system class loader does not have plugin.jar on its classpath.
The example is a bit contrived, but these things happen more frequently in J2EE containers which use complex class loader hierarchies.
Upvotes: 5