> My second problem is what to do if A refers to B statically, rather than
> reflectively. In this case, there is no chance for A to use whatever
> ClassLoader it wishes. Setting the context ClassLoader has no effect
> here. I cannot figure out how to solve this problem. No matter what
> happens, A cannot see B, because A is loaded (even if only by
> delegation) by the system ClassLoader.
I'm not sure what you're trying to do here. If A refers to B
statically, there is no point whatsoever in making A available to the
system classloader without making B available to the system classloader
as well. It will be impossible to ever load the class A, because of
that static reference. Is A part of the plugin, or part of the
framework? If it's part of the plugin, then it should be packaged with
the plugin. If it's part of the framework, then it doesn't make sense
to want to statically reference a class from the plugin. That static
references makes your plugin no longer a plugin at all, and you may as
well not bother with the custom classloader.
I'm racking my brain trying to figure out what you might be trying to do
that would break this. The only thing that comes to mind is this. Are
you requiring that all your plugins define classes with the same fully
qualified name (B)? If so, then you'd be well-advised to abandon that
approach (the dlopen approach to plugins) in favor of letting the plugin
JAR file specify the name of the main plugin class using either a
resource in the JAR file or in the manifest. Then your framework would
never statically reference any plugin class, but would instead call
ClassLoader.loadClass, then Class.newInstance, and then cast the result
to a known superinterface.
> I have a third problem which I haven't really explored very much yet,
> but which is probably going to hit me really hard sometime: what the
> heck does serialization do to all this? What if I want to load a
> serialized version of a B object? How do I make ObjectInputStream use my
> custom ClassLoader?
Good question! A quick Google search suggests that you should extend
ObjectInputStream and override the resolveClass method... but I don't
really know anything more about this than you do. Try that out, and ask
again if it doesn't work.
> The only solution I can think of so far is to use a kind of proxy
> launcher.
You should not need to do this. The question is why your framework
(application) code has a static reference to the plugin code. Once
that's settled, the rest will fall into place.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Chris Head - 29 Jul 2005 21:46 GMT
[snip]
> I'm not sure what you're trying to do here. If A refers to B
> statically, there is no point whatsoever in making A available to the
[quoted text clipped - 6 lines]
> references makes your plugin no longer a plugin at all, and you may as
> well not bother with the custom classloader.
Well, the static reference thing was a bit of a tangent actually; I
*don't* plan to have a static reference to a plugin class in my main
app. I agree, that would be silly in just about every case.
[snip]
> Good question! A quick Google search suggests that you should extend
> ObjectInputStream and override the resolveClass method... but I don't
> really know anything more about this than you do. Try that out, and ask
> again if it doesn't work.
Thanks. I see that it should be quite straightforward. I hadn't done any
Googling because my code is not yet at the point of serialization. I
just wondered if anyone knew offhand whether it would come and hit me or
if the solution is easy.
>>The only solution I can think of so far is to use a kind of proxy
>>launcher.
>
> You should not need to do this. The question is why your framework
> (application) code has a static reference to the plugin code. Once
> that's settled, the rest will fall into place.
I'm not 100% confident with my knowledge of ClassLoaders yet. Somehow it
feels "unnatural" passing instances of classes that come from different
loaders to each other, but that's just me. Once I get things organized I
guess it'll all work out fine, using the custom ClassLoader to load all
plugin classes and making sure than any reference from the application
to a plugin uses the appropriate custom ClassLoader.
Thanks again,
Chris