【发布时间】:2011-04-22 09:29:42
【问题描述】:
我有几个 OSGi 包,每个包都可以从 OSGi 包存储库更新。 当我启动我的 OSGi 框架 (Apache Felix) 时,我希望启动第一个包并检查所有已安装包的更新。如果有可用更新,它应该更新每个更新(包括自身),然后继续启动(或可能关闭,操作系统将重新启动应用程序)。
如何以符合 OSGi 的方式最好地做到这一点?
第一个包应该如何自我更新?它可以在启动时自行更新吗?
【问题讨论】:
标签: osgi
我有几个 OSGi 包,每个包都可以从 OSGi 包存储库更新。 当我启动我的 OSGi 框架 (Apache Felix) 时,我希望启动第一个包并检查所有已安装包的更新。如果有可用更新,它应该更新每个更新(包括自身),然后继续启动(或可能关闭,操作系统将重新启动应用程序)。
如何以符合 OSGi 的方式最好地做到这一点?
第一个包应该如何自我更新?它可以在启动时自行更新吗?
【问题讨论】:
标签: osgi
你应该做几件事:
确保您有一个在框架(重新)启动时首先启动的捆绑包(规范中通常称为“管理代理”),通过为其提供比所有其他捆绑包更低的启动级别。还要确保告诉系统以与管理代理相同的启动级别启动。这样,这个包将能够在框架中的所有其他包真正开始之前更新它们。只有在管理代理完成更新后,它才会刷新所有包并进入下一个启动级别,从而有效地启动所有其他包。
要更新管理代理,最好的方法是临时安装第二个实际执行更新的包。在管理代理中生成线程并不是最好的解决方案,因为一旦捆绑停止并且不遵守这些线程不应该继续运行,可能会给您带来难以解决的问题。如果更新失败,第二个捆绑包实际上会更新,甚至可能回滚。
可以在 Apache ACE 中找到一个可以自我更新的管理代理示例。它有一个代理,它将通过代码安装第二个捆绑包,以从远程位置进行自我更新。一些指向该项目相关部分的指针:
【讨论】:
您可以查看 OSGi 核心规范中的状态图(应该是图 28)。在那里您可以看到处于 STARTING 状态的包只能移动到 ACTIVE 状态(抛出异常时除外)。只有在 INSTALLED 或 RESOLVED 状态下才能更新包。为此必须停止它以防它处于 ACTIVE 状态。
这里的问题是当一个包处于 STARTING 状态时你不能停止它。并且只要 Activators 的 start() 方法被执行,bundle 仍然处于 STARTING 状态,而不是 ACTIVE。
您可以做的是在 Bundle 中启动一个线程,检查其状态是否为 ACTIVE,然后调用 update() 方法。但是不要忘记终止线程,否则垃圾收集器无法释放当前bundle的jar文件的资源。
【讨论】: