Search code examples
javaserviceosgibundleblueprint-osgi

In OSGi, is passing a service reference a good practice or should bundles look it up on their own?


I have these bundles:

  • Comm Service provides a communication service.
  • Communication is a communication bundle that uses the Comm Service to send/receive messages.
  • Poll sends poll messages in multicast mode.

The Communication bundle is saturated and my approach is to implement other bundles for specific actions - the Poll bundle will be responsible for sending polls, the Postcard bundle for sending postcards, etc. (just some examples).

Is the approach to pass the Comm Service service as an input parameter for the Poll bundle when the Communication bundle needs to delegate its work of sending polls/postcards/message?

Is the snippet below correct?

Communication bundle code:

PollBundle p = new PollBundleImpl();
p.sendPoll(String pollQuestion, CommService cs);

Or is the better approach to let the Poll/Postcard bundles to retrieve the Comm Service service on their own?


Solution

  • You must not pass the service object between bundles; if you do this then the OSGi Framework loses control over which bundles have visibility of the service and therefore it cannot inform the full set of bundles when that service needs to go away.

    Therefore the Poll bundle must find the CommService for itself. There are a number of ways of doing this. I strongly recommend using Declarative Services from the OSGi Specification. Used in conjunction with bnd annotations you will be able to write the code of your Poll bundle as follows:

    @Component
    public class Polling {
    
        private CommService commService;
    
        @Reference
        public void setCommService(CommService cs) {
            this.commService = cs;
        }
    
        public void someMethodThatUsesCommService() {
             sendPoll(cs);
             // ...
        }
    }
    

    I recommend this approach over the Blueprint solution described by Jacek Laskowski in his answer because it does not require writing verbose and non-typesafe XML files, and it has better lifecycle characteristics that match the lifecycle of OSGi Services. However both the Declarative Services and Blueprint approaches are certainly safer than mucking about with the low-level OSGi APIs (e.g. ServiceTracker, ServiceListener).