Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a filtering class loader

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?

like image 880
Idan K Avatar asked Jun 22 '10 11:06

Idan K


1 Answers

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.

like image 190
Gilbert Le Blanc Avatar answered Oct 16 '22 16:10

Gilbert Le Blanc