【问题标题】:Can't find service because OSGi bundle isn't activated找不到服务,因为 OSGi 捆绑包未激活
【发布时间】:2011-01-01 19:58:04
【问题描述】:

我在发现某些未激活的 OSGi 捆绑包提供的服务时遇到问题。让我描述一下情况:

  • Bundle A 定义了接口 X
  • 捆绑 B、C 和 D 提供实现接口 X 的服务
    • 这些捆绑包的服务是通过 Spring DM 注册的,因此它们仅在捆绑包被激活并且 Spring DM 初始化捆绑包中定义的应用程序上下文时创建
  • Bundle A 被激活,并且在某个时候向服务注册表询问接口 X 的服务。它没有找到任何服务,因为 bundle B、C 和 D 尚未进入 ACTIVE 状态(它们只是 RESOLVED )。

我似乎无法启动捆绑包 B、C 或 D,因此无法注册它们的服务。通过将它们添加到 config.ini 来强制它们开始不是一个选项,因为可以在应用程序中安装任意数量的包(通过类似 Eclipse p2 的更新机制)实现接口 X。

该应用程序是基于 Eclipse 3.5 的 RCP 应用程序,使用 Spring 2.5.6 和 Spring DM 1.2.1。

如何强制激活这些捆绑包?

【问题讨论】:

  • 您能否提供一些有关您收到的错误消息的信息?并且:Bundle A 导出接口 X,Bundle B、C、D 导入,对吧?
  • 是的,接口X由bundle A导出,由B、C、D导入,没有任何错误信息。在服务注册表中对实现 X 的服务的查询只返回一个空列表。
  • 您在A 中请求的基数是多少?如果是1..N,你就有一个循环依赖。
  • A 中的基数是0..N。您能否详细说明1..N 如何导致循环依赖?我不太明白。
  • 如果是1..N,您将需要一个来自捆绑包BC 的实例,然后才能启动A,但B 和@ 987654332@ 对A 有严格的依赖关系,因此没有一个包能够出现。如果您手动刷新A,然后是B,然后是C,会发生什么?

标签: spring osgi bundle equinox springsource-dm-server


【解决方案1】:

您真正遇到的是依赖层次问题,您提出的骇人听闻的解决方案实际上只是解决潜在问题的创可贴。

您真正应该考虑的是系统的架构,实际上您所拥有的是循环依赖(re: 在 cmets 中讨论您的原始帖子)。您有(喜欢与否)A 需要来自(并且在某种意义上依赖于)B 和 C 的服务。同时,B 和 C 直接依赖于 A,因此,无法在 A 到来之前启动起来。

在最好的情况下,您可以在 B 和 C 中编写代码来侦听 A 的存在,但这充其量掩盖了(正如我所提到的)根本问题。您真正应该考虑的是将 A 拆分为两个捆绑包,我们称它们为 A1 和 A2。

A1 应该提供 B 和 C 需要(依赖)的接口。 A2 应该有 B 和 C 所依赖的服务的侦听器。在启动时,如果 B 和 C 是必需的服务,则必须运行 A1,但 A2 可能稍后启动,并且一切都应该工作。

【讨论】:

  • 我将尝试您的建议,看看会发生什么。谢谢!
【解决方案2】:

我想我已经找到了解决这个问题的方法,虽然感觉有点骇人听闻。

我遇到了this thread,其中 Adrian Colyer 暗示外部“bundle watcher”可能负责在将 bundle 安装到框架中时激活它们。

所以,我的解决方案是:

  • 为捆绑包 B、C 和 D 各自的清单添加自定义标头,例如“MyApp-AutoStart: true”
  • 创建一个捆绑侦听器,在捆绑移动到 RESOLVED 状态时做出响应并查找标头
  • 如果标头的值为“true”,则捆绑侦听器调用bundle.start()

使用这种方法,我想启动的bundle不用config.ini就可以启动了,可以来去自如,但查询时服务可用。

【讨论】:

    【解决方案3】:

    还可以查看 felix fileinstall,它监视目录中的捆绑包并自动安装和启动它们。删除文件时,捆绑软件也会停止并卸载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 2014-01-12
      • 2018-04-22
      • 2014-03-02
      • 1970-01-01
      • 2014-06-03
      相关资源
      最近更新 更多