views:

73

answers:

2

We are extending our java application to support plugins. Part of that includes keeping plugins isolated from our own classes, thus each plugin will live in it's own class loader.

We also plan on giving the plugins a java framework to work with, thus it'll have to be exposed to the plugins. This java framework also contains classes that will need to be accessible from our own java code, therefore it will have to also be accessible to our own java code.

The problem is that if the java framework lives in the system class loader (where our own java code lives), we can't give plugins the isolation we want. If we choose to separate the java framework to a different class loader and use that one as the parent of the plugins class loader, the java framework won't be visible to our own classes.

The current solution I had in mind was to implement a filtering class loader. The java framework will live in the system class loader, but this class loader will filter everything from the system class loader, except for the java framework and I'll use this class loader as the parent class loader of the plugins.

Here's a rough implementation of it:

public class FilteringClassLoader extends ClassLoader {
    private URLClassLoader _internalLoader;

    public FilteringClassLoader(ClassLoader parent) {
        super(parent);

        // load our java framework to this class loader
        _internalLoader = new URLClassLoader(...)
    }

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // first, try to load from our internal class loader
        // that only sees the java framework if that works, load the class 
        // from the system class loader and return that. otherwise, the class 
        // should be filtered out and the call to loadClass will throw as expected
        _internalLoader.loadClass(name);

        Class<?> retClazz = super.loadClass(name);

        return retClazz;
    }
}

However this has several problems the way I see it:

  1. Using a separate URLClassLoader only to see if the class should be filtered feels like a hack to me.
  2. When a plugin loads a class, that class parent class loader will be the system class loader, which obviously defeats the whole purpose of what I'm trying to achieve.

How do you solve this kind of problem?

+2  A: 

How do you solve this kind of problem?

The OSGi Alliance already did. The Wikipedia article on the OSGi framework might give you some ideas.

You might want to look at the source code of Eclipse, and see how they implemented plug in loading.

Gilbert Le Blanc
Do you happen to have any other good intro articles to OSGi? The wikipedia entry seems rather dense.
matt b
You can try this: http://aneeshkumarkb.blogspot.com/ I'm not an OSGi expert, but I have coded Eclipse plug-ins.
Gilbert Le Blanc
This is an invaluable resource, I haven't even heard of this project before (java newbie talking). Seems to me it's a little overkill for our little plugin framework, but it most certainly will prove useful in the future.
Idan K
+2  A: 

If we choose to separate the java framework to a different class loader and use that one as the parent of the plugins class loader, the java framework won't be visible to our own classes.

Put your code in a class loader that is a peer of the plugin class loader, both with the interface code class loader as parent.

Tom Hawtin - tackline
this is a good solution, as long as the API code can be completely isolated from any dependencies on the core app code.
matt b
I also thought of doing it this way, and frankly I might end up choosing this solution. Problems are: (1) what `matt b` said, although for now the framework interface is completely isolated. (2) we have some core pieces of code that for some reason try and access the system class loader directly and if I move all the classes from there it might break a lot of existing code. It might be time to fix that code though.
Idan K