views:

85

answers:

1

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

+2  A: 

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):

A component instance must complete activation before it can be deactivated. Once the component configuration is deactivated or fails to activate due to an exception, SCR must unbind all the component’s bound services and discard all references to the component instance associated with the activation.

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).

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");
    }
}

Cheers, Mirko

Mirko Jahn