自定义OSGi ClassLoader

时间:2014-03-19 05:00:55

标签: dll osgi classloader apache-felix apache-karaf

我想实现自己的自定义ClassLoader。基本上它应该完全是默认的OSGi ClassLoader所做的。

我使用的是Karaf / Felix,所以我的情况是org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader

实现我自己的类加载器的原因是:我使用JNI加载DLL(System.load())。但每次重新部署我的包时,我都会得到一个UnsatisfiedLinkError exception(本地库xyz.dll已经加载到另一个类加载器中)。

这是因为DLL已经由JVM加载 - 并且只要加载它的ClassLoader没有被垃圾回收就会保留。

所以我想做这样的事情:

CustomClassLoader cl = new CustomClassLoader();
Class ca = cl.findClass("myPackage.MyClass");
Object a = ca.newInstance();
Method p = ca.getMethod("myMethod");
p.invoke(a);
p = null;
ca = null;
a = null;
cl = null;
System.gc();

希望在那之后CustomClassLoader被垃圾收集 - 并且从容器中卸载DLL。

我发现奇怪:即使如此,每个捆绑包都有自己的ClassLoader,osgi:uninstall <bundle>也不会卸载DLL - 这意味着捆绑包ClassLoader仍然存活(而不是垃圾回收)。

1 个答案:

答案 0 :(得分:2)

您还在Apache Felix用户列表中提出了这个问题。我的答案是利用OSGi提供的本机代码机制,因为这可以解决您的问题,而不必乱用类加载器。 OSGi提供的机制专门解决了使用本机代码更新bundle的情况,因此它可以很好地解决您的问题。