문제

I am using the SCR framework in an OSGI felix platform to inject service references in my Components. This works great, except for optional dependencies. So if I have two components Foo and Bar, where Foo is given below:

@Component
public class FooImpl implements Foo {
    Log log = LogFactory.getLog(this.getClass());
    @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    Bar bar;

    public void bindBar(Bar bar) {
        log.info("bar bound: "+bar);
    }
    public void unbindBar(Bar map) {
        log.info("bar unbound: "+bar);
    }

    @override
    public void fooHello() {
        log.info("Hello, this is an implementation of Foo");
    }
}

this works, as long as the bundle defining the interface of Bar is deployed in my OSGi platform. If no Bar implementation component is activated in the platform, SCR is still happy and will activate my FooImpl component, ofcourse without reference to any Bar implementation. However, if the Bar interface is not deployed in the platform, SCR crashes during activation of my component, likely due to an exception from the inspection of my component via reflection, but I could not determine that definitively.

So, is there a way to deploy an OSGI bundle with optional dependencies that are not present in the platform that include SCR Components that have optional references to interfaces coming from these optional OSGi dependencies?

도움이 되었습니까?

해결책

OSGi dependencies can be used to inject implementations of some types, like BarImpl class implementing Bar interface which can be injected to @Reference Bar bar field. Optional dependencies mean that your OSGi component can use some service, but doesn't require it to work.

However, if OSGi doesn't know type you are trying to use as a field, you will get an exception and it is a valid behaviour. You simply can't use a class if its field has unknown type - and its true not only for OSGi but for Java in general.

A good approach here is to split bundle containing Bar implementation to two bundles:

  • bar-api containing Bar interface,
  • bar-impl containing OSGi service BarImpl.

bar-api is still required by FooImpl, but bar-impl is truly optional and disabling it in the Felix console won't break referencing components.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top