Stephen Winnall February 2016

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        

Answers


Christian Schneider February 2016

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.


Stephen Winnall February 2016

I've solved the problem after stripping the application right down to the basics, which in this case is the code to start the Felix framework.

The key to the problem was the recognition that an OSGi framework embedded in a normal Java program is a meeting of two worlds: bundles and POJOs. These days lots of POJOs are distributed with OSGi-compatible manifests, but they are still POJOs and not bundles. But I was sticking everything with an OSGi manifest into the bundles directory and loading them with AutoProcessor.process(). This included things like org.apache.felix.framework and org.apache.felix.main, but also various POJOs dealing with logging. That seems to have caused the behaviour described above.

I fixed this by linking org.apache.felix.framework, org.apache.felix.main and the logging POJOs in the classic fashion and excluding them from AutoProcessor.process().

Unfortunately, slf4j-api seems to lead a double life, and there are lots of bundles out there, some of which I am using, which need it as a bundle. Rather than experiment with loading it twice (classical linking and AutoProcessor.process()) I simply added pax-logging-api and pax-logging-service to my bundles directory and let AutoProcessor.process() load them instead.

It all makes perfect sense with hindsight ;-)

Post Status

Asked in February 2016
Viewed 3,778 times
Voted 14
Answered 2 times

Search




Leave an answer