2010-06-22 78 views
7

我们正在扩展我们的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. 当一个插件加载一个类时,该类的父类加载器将成为系统类加载器,这明显破坏了我试图实现的全部目的。

您如何解决这类问题?

+0

这与在JRE库中引入'com.sun'包的依赖关系的人有什么不同吗?还是有进一步的限制? – McDowell 2010-06-22 11:10:19

+0

不知道你的意思 – 2010-06-22 13:14:23

回答

2

你如何解决这类问题?

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

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

+0

你碰巧有任何其他好的介绍文章给OSGi吗?维基百科条目似乎相当密集。 – 2010-06-22 11:41:18

+0

你可以试试这个:http://aneeshkumarkb.blogspot.com/我不是OSGi专家,但是我编写了Eclipse插件。 – 2010-06-22 11:44:14

+0

这是一个非常宝贵的资源,我甚至没有听说过这个项目(Java新手谈话)。对我来说,对我们的小插件框架来说有点矫枉过正,但它肯定会在将来证明有用。 – 2010-06-22 13:21:44

2

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

将您的代码放入一个类加载器中,该加载器是插件类加载器的一个对象,它们都以接口代码类加载器作为父类。

+0

这是一个很好的解决方案,只要API代码可以完全与核心应用程序代码的任何依赖关系隔离即可。 – 2010-06-22 11:53:27

+0

我也想过这样做,坦率地说,我可能会选择这个解决方案。问题是:(1)'matt b'说了什么,虽然现在框架界面是完全隔离的。 (2)我们有一些核心代码,出于某种原因直接尝试和访问系统类加载器,如果我从那里移动所有类,它可能会破坏很多现有的代码。虽然可能是修复该代码的时候了。 – 2010-06-22 13:20:06