在服务启动时禁用 OSGi 服务的正确方法是什么?
我创建了一个带有公开(声明性)服务的 OSGi 包。如果我在调用 activate 时发现有些问题导致我无法提供服务,我需要防止它被暴露。目前激活函数看起来像这样:
public void activate(ComponentContext context, Map<String, Object> properties) {
pid = (String) properties.get(Constants.SERVICE_PID);
try {
...
}
catch(Exception e) {
context.disableComponent(pid);
}
}
另一种选择是只包装/传播异常(或抛出一个新的异常,具体取决于),如下所示:
public void activate(ComponentContext context, Map<String, Object> properties) {
try {
...
}
catch(Exception e) {
throw new ComponentException("Some reason");
}
}
我找不到 OSGi 服务平台服务纲要,但我可能会遗漏一些东西
I have created an OSGi bundle with an exposed (declarative) service. If I, when activate is called, notice that something is amiss such that I can not provide the service, I need to prevent it from being exposed. At the moment the activation function looks like so:
public void activate(ComponentContext context, Map<String, Object> properties) {
pid = (String) properties.get(Constants.SERVICE_PID);
try {
...
}
catch(Exception e) {
context.disableComponent(pid);
}
}
Another alternative is to just wrap/propagate the exception (or throw a new one, depending) like this:
public void activate(ComponentContext context, Map<String, Object> properties) {
try {
...
}
catch(Exception e) {
throw new ComponentException("Some reason");
}
}
I can not find the correct behavior specified in the section on declarative services in the OSGi Service Platform Service Compendium, but I might be missing something
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯,对我来说,如果发生错误,应该抛出异常似乎是合乎逻辑的。基本上,您所做的就是在 start 方法中模仿 BundleActivator 的行为。当 start 方法返回且没有出现异常时,bundle 就进入 ACTIVE 状态(否则它仍处于 RESOLVED 状态)。我在 DS 规范中找到了一段有点合适的段落(我突出显示了有趣的部分):
OSGi 4.2 cmpn 规范中的第 112.5.6 P.320 节
我同意这不是很清楚,所以如果你想安全起见(安全总比后悔好),我建议进行组合(规范允许)。
干杯,
米尔科
Hmm, for me it seems logical that an Exception should be thrown if an error occurs. Basically, what you're doing then is mimicking the behavior of a BundleActivator in the start method. The bundle enters the ACTIVE state when the start method returns without an Exception (otherwise it remains in RESOLVED). I found a somewhat fitting paragraph in the DS specification (I highlighted the interesting part):
Section 112.5.6 P.320 in the OSGi 4.2 cmpn spec
I agree that this is not crystal clear, so if you want to be on the safe side (better safe than sorry), I would recommend to do the combination (allowed by the spec).
Cheers,
Mirko
禁用自身的组件不太可能是合适的 OSGI 设计。当情况改善时,什么会启用该组件?启用/禁用状态旨在成为与激活/停用不同的逻辑级别。
正确设计的 OSGI 代码应该正确处理激活失败时抛出 ComponentException(或其他异常)的代码。假设组件注册了一个服务,服务引用将可用,但尝试获取该服务将返回 null。 DS 将正确处理对服务的引用,任何直接尝试从服务引用获取服务的代码都必须正确处理服务实际上不可用的可能性。
然而,这可能会令人困惑。在 Felix DS 中,我实现了一个扩展,组件可以通过该扩展更改自己的服务属性,尽管这尚未被规范接受。使用此扩展,组件可以在激活或修改成功时添加服务属性,例如 active=true,并在修改失败或停用时删除它。服务的客户端可以过滤该服务属性,例如(active=true)。
A component disabling itself is very unlikely to be an appropriate OSGI design. What will enable the component when the situation improves? The enabled/disabled state is intended to be a different logical level than activated/deactivated.
Properly designed OSGI code should deal correctly with code that throws a ComponentException (or other exception) when activation fails. Assuming the component registers a service, the service reference will be available but attempting to get the service will return null. DS will deal correctly with references to the service, and any code that directly attempts to get the service from the service reference must deal properly with the possibility that the service is not actually available.
However, this can be confusing. In Felix DS I implemented an extension whereby components can change their own service properties, although this has not been accepted into the spec. Using this extension, a component can add a service property such as active=true when activation or modification succeeds and remove it when modification fails or on deactivation. Clients of the service can filter on this service property, e.g. (active=true).