在服务启动时禁用OSGi服务的正确方法是什么?

Hen*_*son 9 java osgi declarative-services

我创建了一个带有暴露(声明)服务的OSGi包.如果我,当调用激活时,注意到某些东西是不对的,这样我就无法提供服务,我需要防止它暴露.目前激活功能如下:

public void activate(ComponentContext context, Map<String, Object> properties) {
    pid = (String) properties.get(Constants.SERVICE_PID);
    try {
       ...
    }
    catch(Exception e) {
        context.disableComponent(pid);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是只包装/传播异常(或抛出一个新异常,取决于),如下所示:

public void activate(ComponentContext context, Map<String, Object> properties) {
    try {
       ...
    }
    catch(Exception e) {
        throw new ComponentException("Some reason");
    }
}
Run Code Online (Sandbox Code Playgroud)

我找不到OSGi Service Platform Service Compendium中关于声明性服务的部分中指定的正确行为,但我可能会遗漏某些内容

Mir*_*ahn 9

嗯,对我来说,如果发生错误,应该抛出异常似乎是合乎逻辑的.基本上,你正在做的是在start方法中模仿BundleActivator的行为.当start方法返回而没有Exception时,bundle进入ACTIVE状态(否则它保持在RESOLVED状态).我在DS规范中找到了一个有点合适的段落(我突出了有趣的部分):

组件实例必须先完成激活才能取消激活.一旦组件配置被停用或由于异常而无法激活,SCR必须取消绑定所有组件的绑定服务,并丢弃对与激活相关联的组件实例的所有引用.

OSGi 4.2 cmpn规范中的第112.5.6节P.320

我同意这不是很清楚,所以如果你想保持安全(更安全而不是遗憾),我会建议做组合(规范允许).

public void activate(ComponentContext context, Map<String, Object> properties) {
    try {
       ...
    } catch(Exception e) {
        context.disableComponent((String) properties.get(Constants.SERVICE_PID));
        // not sure if a CE is best here... Maybe just rethrow the original one
        throw new ComponentException("Some reason");
    }
}
Run Code Online (Sandbox Code Playgroud)

干杯,米尔科