Osgi 在嵌入式Felix框架中使用声明性服务

Osgi 在嵌入式Felix框架中使用声明性服务,osgi,apache-felix,declarative-services,Osgi,Apache Felix,Declarative Services,我正在使用Netbeans和Maven在macosx上开发一个带有声明性服务的桌面OSGi应用程序。我从Java应用程序中启动Felix框架,并使用AutoProcessor.process()加载我的OSGi包 但是,我无法激活其他服务中引用的服务。例如,我有一个serviceAImpl,它引用serviceB,如下所示: interface A {} interface B {} @Component @Service(A.class) class AImpl implements A

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

但是,我无法激活其他服务中引用的服务。例如,我有一个service
AImpl
,它引用service
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.jar
org.apache.felix.scr.compat-1.0.2.jar
),但这似乎还不够

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

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


我在谷歌上搜索过像felix ds embedded这样的术语,并找到了像这样的文章,这使它听起来像我希望的那样简单。很明显,我在某个地方犯了一个错误:我会感谢你的指点。

你所做的乍一看很好。没有所有的细节很难说

您似乎正在使用scr注释。由于现在有标准的DS注释,我建议您尝试一下。我得到了一份工作

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

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

如果这样做有效,那么您的捆绑包是正确的,并且您的felix部署可能存在问题


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

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

问题的关键在于认识到嵌入到普通Java程序中的OSGi框架是两个世界的结合:bundle和POJO。现在很多POJO都是使用OSGi兼容的清单发布的,但它们仍然是POJO而不是捆绑包。但是我把所有带有OSGi清单的东西都粘贴到bundles目录中,并使用
AutoProcessor.process()
加载它们。这包括
org.apache.felix.framework
org.apache.felix.main
,但也包括处理日志的各种POJO。这似乎导致了上述行为

我以经典方式链接了
org.apache.felix.framework
org.apache.felix.main
和日志POJO,并将它们从
AutoProcessor.process()中排除,从而解决了这个问题

不幸的是,
slf4japi
似乎过着双重生活,有很多捆绑包,其中一些我正在使用,它们需要它作为捆绑包。我没有尝试加载两次(经典链接和
AutoProcessor.process()
),而是简单地将
pax日志api
pax日志服务
添加到我的bundles目录中,让
AutoProcessor.process()
加载它们


事后看来,这一切都很有道理;-)

谢谢你的反馈:我会逐一检查你的观点,看看是否能找出问题所在。我从您的回复中推断,从嵌入式Felix框架启动声明性服务时,除了加载适当的
org.apache.Felix.scr
bundle.Yes之外,不需要任何特殊步骤。scr束应该足够了。对于新功能,您可能还需要一个合理的新Felix,但我不确定是否需要。您可以尝试从框架中检索BundleContext,并在循环中遍历bundle以打印其状态。在测试中,我也经常简单地启动循环中的每个包。如果启动或解决不成功,则会打印出异常。