【发布时间】:2023-03-07 01:35:01
【问题描述】:
我想实现我自己的自定义 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 仍然存在(而不是垃圾收集)。
【问题讨论】:
-
另外,我不确定您关于类加载器被垃圾收集的说法是否会导致通过类加载器加载的任何共享对象 (DLL) 从 VM 进程中“卸载”。你有任何关于这种行为的文档吗?
-
例如看这个:tech-tauk.blogspot.de/2009/11/…“当找到库的类加载器在垃圾收集期间从堆中收集时,JVM会卸载本机库。”
-
那是一篇博客文章,不具有权威性。我正在考虑 Oracle/OpenJDK 关于这个问题的文档。
标签: dll osgi classloader apache-felix apache-karaf