【问题标题】:Using declarative services with embedded Felix framework使用带有嵌入式 Felix 框架的声明式服务
【发布时间】:2016-05-18 19:59:43
【问题描述】:

我正在使用 Netbeans 和 Maven 在 Mac OS X 上开发一个带有声明式服务的桌面 OSGi 应用程序。我从 Java 应用程序中启动 Felix 框架,并使用 AutoProcessor.process() 加载我的 OSGi 包。

但是,我无法激活其他服务中引用的服务。例如,我有一个服务AImpl,它指的是服务B,如下所示:

interface A {}

interface B {}

@Component
@Service(A.class)
class AImpl implements A {
    @Reference(strategy = EVENT)
    B b;
    ...
}

@Component
@Service(B.class)
class BImpl implements B { ... }

在我创建了A 类型的捆绑包后,AImpl.b 的值始终为null

我启动 Felix 框架的代码如下所示:

Map felixConfiguration = ...;

try {
    framework = new Felix(felixConfiguration);
    framework.init();

    final BundleContext frameworkBundleContext = framework.
                getBundleContext();

    AutoProcessor.process(felixConfiguration, frameworkBundleContext);

    framework.start();

    framework.waitForStop(0);
    System.exit(0);

} catch (Exception ex) {
    log.error("Could not start framework", ex);
    System.exit(-1);
}

felixConfiguration 包含(其中包括)要加载包含 DS 服务的包的目录的定义。

但是,我收到如下错误消息:

 DEBUG: BundleA (12): [AImpl(6)] Updating target filters
 DEBUG: BundleA (12): [AImpl(6)] No change in target property for dependency b: currently registered: false
 DEBUG: BundleA (12): [AImpl(6)] No existing service listener to unregister for dependency b
 DEBUG: BundleA (12): [AImpl(6)] Setting target property for dependency b to null
 DEBUG: BundleA (12): [AImpl(6)] New service tracker for b, initial active: false, previous references: {}
 DEBUG: BundleA (12): [AImpl(6)] dm b tracker reset (closed)
 DEBUG: BundleA (12): [AImpl(6)] dm b tracker opened
 DEBUG: BundleA (12): [AImpl(6)] registering service listener for dependency b
 DEBUG: BundleA (12): [AImpl(6)] Component enabled
 DEBUG: BundleA (12): [AImpl(6)] ActivateInternal
 DEBUG: BundleA (12): [AImpl(6)] Activating component from state 4
 DEBUG: BundleA (12): [AImpl(6)] Dependency not satisfied: b
 DEBUG: BundleA (12): [AImpl(6)] Not all dependencies satisfied, cannot activate

在我看来,缺少一些 SCR 代码会使 Felix 框架处理 DS 服务。我在依赖项中包含了org.apache.felix.scr-1.8.2.jar(或者org.apache.felix.scr-2.0.2.jarorg.apache.felix.scr.compat-1.0.2.jar),但这似乎还不够。

另外一个症状,我认为它与同一个问题有关:gogo 启动但无法识别像 helplb 等命令,尽管所有三个包(命令、运行时、shell)都是可用。

我已经简化了示例并更改了相关各方的名称以保护无辜者 :-) 我希望结构足够清晰,以显示我正在尝试做什么以及什么不起作用。

我搜索了felix ds embedded 之类的术语,并找到了this 之类的文章,这听起来就像我希望的那样简单。显然我在某个地方犯了一个错误:我将不胜感激。

【问题讨论】:

    标签: osgi apache-felix declarative-services


    【解决方案1】:

    乍一看,您所做的事情看起来不错。没有所有细节很难说。

    您似乎正在使用 scr 注释。由于现在有标准的 DS 注释,我建议您尝试一下。我有一个full example here

    我通常使用 karaf 作为示例,但它也应该适用于普通的 felix。

    您可以尝试的一件事是将您的捆绑包安装到 karaf 并使用 karaf shell 来分析是否有任何异常。只需安装 scr 功能并将您的捆绑包放入部署目录。

    如果可行,那么您的捆绑包是正确的,并且您的 felix 部署可能存在问题。

    在任何情况下,您都应该检查是否可以解析所有捆绑包。当然,只要shell不工作,这有点困难。

    【讨论】:

    • 感谢您的反馈:我会一一分析您的观点,看看能否找出问题所在。我从您的回复中推断,除了加载适当的 org.apache.felix.scr 包之外,从嵌入式 Felix 框架启动声明性服务时不需要特殊步骤。
    • 是的。 scr 包应该足够了。对于新功能,您可能还需要一个相当新的 Felix,但我不确定这是否需要。您可以尝试从框架中检索 BundleContext 并循环遍历捆绑包以打印它们的状态。在测试中,我也经常简单地启动循环中的每个包。如果启动或解析不成功,这将打印出一个异常。
    【解决方案2】:

    在将应用程序剥离到基础之后,我已经解决了这个问题,在本例中是启动 Felix 框架的代码。

    问题的关键在于认识到嵌入在普通 Java 程序中的 OSGi 框架是两个世界的交汇点:bundle 和 POJO。如今,许多 POJO 都与 OSGi 兼容的清单一起分发,但它们仍然是 POJO,而不是捆绑包。但是我将所有带有 OSGi 清单的东西都粘贴到 bundles 目录中,并使用AutoProcessor.process() 加载它们。这包括 org.apache.felix.frameworkorg.apache.felix.main 之类的东西,还包括各种处理日志记录的 POJO。这似乎导致了上述行为。

    我通过以经典方式链接 org.apache.felix.frameworkorg.apache.felix.main 和日志记录 POJO 并将它们从 AutoProcessor.process() 中排除来解决此问题。

    不幸的是,slf4j-api 似乎过着双重生活,那里有很多捆绑包,其中一些我正在使用,它们需要它作为捆绑包。我没有尝试加载它两次(经典链接和AutoProcessor.process()),而是将pax-logging-apipax-logging-service 添加到我的bundles 目录中,然后让AutoProcessor.process() 加载它们。

    事后看来,这一切都说得通;-)

    【讨论】:

      猜你喜欢
      • 2013-10-09
      • 2022-07-28
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 2015-08-26
      • 2010-09-23
      • 2012-04-27
      相关资源
      最近更新 更多