Search code examples
osgiapache-felixdeclarative-services

Using declarative services with embedded Felix framework


I am developing a desktop OSGi app with declarative services on Mac OS X using Netbeans and Maven. I start the Felix framework from within a Java application and load my OSGi bundles using AutoProcessor.process().

However, I cannot get services referenced in other services to activate. As an example, I have a service AImpl which refers to service B as follows:

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 { ... }

The value of AImpl.b is always null after I have created a bundle of type A.

My code to start the Felix framework looks like this:

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 contains – amongst many other things – the definition of the directory from which the bundles containing the DS services are to be loaded.

However, I get error messages like the following:

 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

It seems to me that some SCR code is missing that will make the Felix framework deal with DS services. I have included org.apache.felix.scr-1.8.2.jar (and alternatively org.apache.felix.scr-2.0.2.jar and org.apache.felix.scr.compat-1.0.2.jar) in the dependencies, but that does not seem to be enough.

An additional symptom, which I assume is related to the same problem: gogo starts but doesn't recognise commands like help, lb etc., although all three bundles (command, runtime, shell) are available.

I have simplified the examples and changed the names of the parties involved to protect the innocent :-) I hope that the structure is clear enough to show what I am trying to do and what is not working.

I have googled terms like felix ds embedded and found articles like this, which make it sound as easy as I wish it was. Clearly I am making a mistake somewhere: I'd be grateful for pointers.


Solution

  • What you do looks good at first glance. It is difficult to tell without all details.

    You seem to be using the scr annotations. As there are standard DS annotations now I propose you give them a try. I got a full example here.

    I typically use karaf for my examples but it should also work in plain felix.

    One thing your could try is to install your bundles into karaf and use the karaf shell to analyze if there is anything strange. Just install the scr feature and put your bundles into the deploy dir.

    If that works then your bundle are correct and there is probably a problem with your felix deployment.

    In any case you should check that all bundles can be resolved. Of course this is a bit difficult as long as the shell does not work.