Java 实现过滤类加载器

Java 实现过滤类加载器,java,classloader,Java,Classloader,我们正在扩展java应用程序以支持插件。其中的一部分包括保持插件与我们自己的类隔离,这样每个插件都将生活在它自己的类加载器中 我们还计划为插件提供一个java框架来使用,因此它必须向插件公开。这个java框架还包含需要从我们自己的java代码访问的类,因此它也必须可以从我们自己的java代码访问 问题是,如果java框架存在于系统类装入器中(我们自己的java代码所在的地方),我们就不能给插件提供我们想要的隔离。如果我们选择将java框架分离到不同的类加载器,并将其用作插件类加载器的父类,那么j

我们正在扩展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;
    }
}
公共类过滤器ClassLoader扩展了ClassLoader{
私有URLClassLoader\u internalLoader;
公共筛选器ClassLoader(ClassLoader父级){
超级(家长);
//将java框架加载到此类加载器
_internalLoader=新的URLClassLoader(…)
}
公共类loadClass(字符串名称)引发ClassNotFoundException{
//首先,尝试从我们的内部类加载器加载
//这只会看到java框架,如果可以的话,加载类
//从系统类加载器返回。否则,类
//应该过滤掉,对loadClass的调用将按预期抛出
_loadClass(名称);
Class retClazz=super.loadClass(名称);
返回重新分类;
}
}
然而,在我看来,这有几个问题:

  • 在我看来,使用单独的URLClassLoader只是为了查看类是否应该被过滤,这就像是一种黑客行为
  • 当插件加载一个类时,该类的父类加载器将是系统类加载器,这显然违背了我试图实现的全部目的
  • 你如何解决这类问题

    你如何解决这类问题

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

    您可能希望查看的源代码,并了解它们是如何实现插件加载的

    如果我们选择将java框架分离到不同的类加载器,并将其用作插件类加载器的父类,那么java框架对我们自己的类将不可见


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

    这与人们在JRE库中引入依赖项
    com.sun
    包有什么不同吗?或者还有进一步的限制?你有没有其他关于OSGi的好的介绍文章?wikipedia条目似乎相当密集。你可以试试这个:我不是OSGi专家,但我编写了Eclipse插件。这是一个非常宝贵的资源,我以前甚至没有听说过这个项目(java新手在说)。在我看来,这对于我们的小插件框架来说有点过分了,但它肯定会在未来被证明是有用的……更重要的是,关于OSGi的解决方案,请查看Rob Evans关于“设置上下文类加载器”的示例。其基本思想是让activator生成一个执行thread.currentThread().setContextClassLoader(classLoader)的线程,这是一个类加载器,您可以稍后使用get()获取它。要为您自己的上下文创建一个委托加载器,请查看其BundleClassloader的源代码并从中获取:这是一个很好的解决方案,只要API代码可以与核心应用程序代码的任何依赖完全隔离,我也想过这样做,坦白地说,我最终可能会选择这个解决方案。问题是:(1)matt b所说的,尽管目前框架接口是完全隔离的。(2) 我们有一些核心代码,出于某种原因,它们试图直接访问系统类加载器,如果我将所有类从那里移走,可能会破坏很多现有代码。不过,现在可能是修复该代码的时候了。