实现过滤类加载器

时间:2010-06-22 11:03:11

标签: java classloader

我们正在扩展我们的java应用程序以支持插件。其中一部分包括保持插件与我们自己的类隔离,因此每个插件都将存在于它自己的类加载器中。

我们还计划为插件提供一个可以使用的java框架,因此它必须暴露给插件。这个java框架还包含需要从我们自己的java代码访问的类,因此它也必须可以访问我们自己的java代码。

问题是如果java框架存在于系统类加载器(我们自己的java代码所在的位置)中,我们就无法为插件提供我们想要的隔离。如果我们选择将java框架分离到另一个类加载器并使用它作为插件类加载器的父类,那么我们自己的类将无法看到java框架。

我想到的当前解决方案是实现过滤类加载器。 java框架将存在于系统类加载器中,但是这个类加载器将过滤掉系统类加载器中的所有东西,除了java框架,我将使用这个类加载器作为插件的父类加载器。

这是一个粗略的实现:

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;
    }
}

然而,我认为这有几个问题:

  1. 仅使用单独的URLClassLoader来查看是否应该过滤该类,这对我来说就像是黑客攻击。
  2. 当插件加载一个类时,该类父类加载器将成为系统类加载器,这显然违背了我想要实现的目的。
  3. 你如何解决这类问题?

2 个答案:

答案 0 :(得分:2)

  

你如何解决这类问题?

OSGi联盟已经做到了。关于OSGi framework的维基百科文章可能会给你一些想法。

您可能需要查看Eclipse的源代码,看看它们是如何实现插件加载的。

答案 1 :(得分:2)

  

如果我们选择将java框架分离到另一个类加载器并使用它作为插件类加载器的父类,那么我们自己的类将无法看到java框架。

将您的代码放在一个类加载器中,该类加载器是插件类加载器的对等,两者都将接口代码类加载器作为父类。