让我们说我有一个包含组件B的Bundle A,它不是Export-Package的一部分。该组件将安排自己在激活后定期运行。调度程序由另一个包提供。
我的问题是,如果我卸载Bundle A而组件B正由调度程序的线程池中的一个线程运行,那将是什么意思呢?线程会继续运行吗?或者线程会抛出异常?
答案 0 :(得分:5)
捆绑包具有生命周期。当捆绑包处于活动状态时,它将在卸载之前停止。如果“组件B”是声明性服务组件,它也将被停止。如果没有,那么至少会触发bundle激活器中的stop方法。
在停止期间,您(作为组件B的提供者)负责从计划中取消调度组件,以便将其从线程池中删除。如果线程当前正在运行,那么您应该实现取消功能,以便可以中止它。
如果没有正确清理(即取消调度/取消线程),则可能会再次执行该线程。如果您从该线程中访问OSGi API,那么您将获得IllegaleStateException(对于某些API使用,因为bundle的BundleContext在被停止后变为无效)。但是,如果没有,那么你的线程可能会继续运行。对象和内存不会被释放。类和bundle类加载器不会被垃圾回收。因此,正确实施“停止”非常重要。
答案 1 :(得分:3)
如果使用代理引用绑定模块,那么在替换模块之前,这些代理可能无效。
如果你有直接绑定,那么"卸载"在任何地方都没有使用模块之前,模块并没有真正删除您可以替换它,新用户将使用新库。
答案 2 :(得分:3)
OSGi中没有魔法,维护对象的现有引用并防止垃圾收集器收获相应的类加载器。
幸运的是,DS可以很容易地进行相应的清理工作。