在其他线程引用的已卸载的OSGi包中的对象会发生什么?

时间:2012-08-10 10:44:06

标签: java osgi

让我们说我有一个包含组件B的Bundle A,它不是Export-Package的一部分。该组件将安排自己在激活后定期运行。调度程序由另一个包提供。

我的问题是,如果我卸载Bundle A而组件B正由调度程序的线程池中的一个线程运行,那将是什么意思呢?线程会继续运行吗?或者线程会抛出异常?

3 个答案:

答案 0 :(得分:5)

捆绑包具有生命周期。当捆绑包处于活动状态时,它将在卸载之前停止。如果“组件B”是声明性服务组件,它也将被停止。如果没有,那么至少会触发bundle激活器中的stop方法。

在停止期间,您(作为组件B的提供者)负责从计划中取消调度组件,以便将其从线程池中删除。如果线程当前正在运行,那么您应该实现取消功能,以便可以中止它。

如果没有正确清理(即取消调度/取消线程),则可能会再次执行该线程。如果您从该线程中访问OSGi API,那么您将获得IllegaleStateException(对于某些API使用,因为bundle的BundleContext在被停止后变为无效)。但是,如果没有,那么你的线程可能会继续运行。对象和内存不会被释放。类和bundle类加载器不会被垃圾回收。因此,正确实施“停止”非常重要。

答案 1 :(得分:3)

如果使用代理引用绑定模块,那么在替换模块之前,这些代理可能无效。

如果你有直接绑定,那么"卸载"在任何地方都没有使用模块之前,模块并没有真正删除您可以替换它,新用户将使用新库。

答案 2 :(得分:3)

OSGi中没有魔法,维护对象的现有引用并防止垃圾收集器收获相应的类加载器。

幸运的是,DS可以很容易地进行相应的清理工作。