Search code examples
javaosgiosgi-bundle

Find out which bundle calls service


In equinox OSGi, I am using a service (DS) from several different bundles and I would like to know in the service who is using it, each time.

The service write to the database, and I want to know which bundle writes what.

The buildin LogService must be able to do this, since it knows who wrote each log line, but I can't figure out how.

The simplest solution is to put the name of the bundle in each method to the service, but I hope for a more elegant solution.


Solution

  • This is precisely what a ServiceFactory is for, see OSGi Core R6 specification Section 5.9. "Service Factory".

    Updated Below after question clarified to specify DS usage.

    This can be achieved by using scope=ServiceScope.BUNDLE on your @Component annotation. Then you can access the calling bundle by allowing the ComponentContext to be injected into your activate method and calling getUsingBundle(). For example:

    @Component(scope = ServiceScope.BUNDLE)
    public class MyComponent implements MyService {
    
        private Bundle usingBundle;
    
        @Activate
        void activate(ComponentContext context) {
            this.usingBundle = context.getUsingBundle();
        }
    
        // ... 
    }
    

    At the low-level this works by registering the service as an instance of ServiceFactory rather than a plain service object. When OSGi obtains the service on behalf of a consumer, it invokes the getService method, which passes the consumer Bundle object to the provider of the service. This happens entirely transparently for the consumer, i.e. they don't have to change their code at all.