代码之家  ›  专栏  ›  技术社区  ›  Idan K

实现筛选类加载器

  •  7
  • Idan K  · 技术社区  · 14 年前

    我们正在扩展我们的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. 当一个插件加载一个类时,这个类父类加载器将是系统类加载器,这显然会破坏我所要实现的目标。

    你如何解决这种问题?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Gilbert Le Blanc    14 年前

    你如何解决这种问题?

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

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

        2
  •  2
  •   Tom Hawtin - tackline    14 年前

    如果我们选择将Java框架拆分为不同的类加载器,并将其用作插件类加载器的父级,则Java框架对于我们自己的类将是不可见的。

    将代码放在插件类加载器的对等类加载器中,两者都以接口代码类加载器为父级。