使用带有嵌入式Felix框架的声明式服务

时间:2016-02-09 00:18:22

标签: osgi apache-felix declarative-services

我正在使用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 { ... }

创建AImpl.b类型的包后,null的值始终为A

启动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

在我看来,缺少一些可以使Felix框架处理DS服务的SCR代码。我已将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这样的文章,这听起来像我希望的那样简单。显然我在某个地方犯了一个错误:我很感激指针。

2 个答案:

答案 0 :(得分:0)

乍一看,你的表现看起来不错。没有所有细节很难说清楚。

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

我通常使用karaf作为我的例子,但它也应该在普通的felix中使用。

你可以尝试的一件事是将你的软件包安装到karaf并使用karaf shell来分析是否有任何奇怪的东西。只需安装scr功能并将捆绑包放入deploy dir即可。

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

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

答案 1 :(得分:0)

在将应用程序剥离到基础知识之后,我已经解决了这个问题,在本例中是启动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-api添加到我的包目录中,然后让pax-logging-service加载它们,而不是尝试加载两次(经典链接和AutoProcessor.process())。

后见之明这一切都很完美; - )