我正在使用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.jar
和org.apache.felix.scr.compat-1.0.2.jar
)包含在依赖项中,但这似乎还不够。
我认为另一个症状与同一问题有关:gogo
启动但不识别help
,lb
等命令,尽管所有三个捆绑(命令) ,运行时,shell)可用。
我简化了示例并更改了相关各方的名称以保护无辜者:-)我希望结构足够清晰,以显示我正在尝试做什么以及什么不起作用。
我搜索过像felix ds embedded
这样的字词,并找到像this这样的文章,这听起来像我希望的那样简单。显然我在某个地方犯了一个错误:我很感激指针。
答案 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.framework
和org.apache.felix.main
等内容,以及处理日志记录的各种POJO。这似乎导致了上述行为。
我通过以经典方式链接org.apache.felix.framework
,org.apache.felix.main
和日志记录POJO并将其从AutoProcessor.process()
中排除来解决此问题。
不幸的是,slf4j-api
似乎带来了双重生命,并且有很多捆绑,其中一些是我正在使用的,需要它作为捆绑。我只是将AutoProcessor.process()
和pax-logging-api
添加到我的包目录中,然后让pax-logging-service
加载它们,而不是尝试加载两次(经典链接和AutoProcessor.process()
)。
后见之明这一切都很完美; - )