Getting OSGi services from a bundle in Sling/CQ

23,008

Solution 1

To get a service from a java OSGi component you don't need the SlingScriptHelper, you can either use the BundleContext.getService(...) method, or use SCR annotations to let SCR inject the service in your component.

As an example, you can look at how some components in Sling's Slingbucks sample use SCR annotations, the ConfirmedOrdersObserver class for example gets the SlingRepository in this way:

   @Reference
   private SlingRepository repository;

See http://felix.apache.org/site/apache-felix-maven-scr-plugin.html for the Maven plugin that handles these annotations.

Solution 2

You can use the BundleContext to get to the Service, by using the #getServiceReference and #getService methods. For example, if you were interested in the ResourceResolverFactory, you could get it like so:

BundleContext bundleContext = FrameworkUtil.getBundle(MyClass.class).getBundleContext();
ServiceReference factoryRef =
     bundleContext.getServiceReference(ResourceResolverFactory.class.getName());
ResourceResolverFactory resolverFactory = 
    (ResourceResolverFactory) bundleContext.getService(factoryRef);

Solution 3

YourClass obj = this.getSlingScriptHelper().getService(yourclass.class);
obj.whatever();
Share:
23,008
joelt
Author by

joelt

Updated on August 25, 2020

Comments

  • joelt
    joelt almost 4 years

    I am using Day CQ. I want to store some data in a SQL Server DB, using the connection pool available in the Felix console. I can do this from a JSP, by using the "sling" object of type SlingScriptHelper defined in the defineObjects tag

    sling.getService(DataSourcePool.class).
    

    However, I want to use a servlet created in an OSGi bundle to handle requests from the client. The servlet doesn't have a defineObjects tag, so the "sling" object is not defined. I don't see a way to create a valid SlingScriptHelper object in my servlet, but it seems like it has to be possible.

    Is there a way?

  • joelt
    joelt over 12 years
    I was able to use the SCR annotation approach. How would I get an instance of the BundleContext, though? That was something I wasn't able to figure out.
  • joelt
    joelt over 12 years
    I haven't tested this out, but I'm thinking it could be done using the activate() or perhaps bind() methods.
  • empire29
    empire29 over 12 years
    In the activate(..) and deactivate(..) take a osgi ComponentContext object. From this obj you can derive the BundleContext. You shouldn't need the bundle context object tho as Bertrand indicated; you just need to use DCS instantiate your objects in your servlet (which is sling service).
  • Bertrand Delacretaz
    Bertrand Delacretaz over 12 years
    empire29 is correct, if you use SCR you can get the BundleContext from the activate/deactivate method parameters. You usually don't need BundleContext.getService(...) when you use SCR, @Reference will be sufficient in most cases.
  • Jeremy Grand-Scrutton
    Jeremy Grand-Scrutton almost 11 years
    I tried using @Reference annotations to add services to my bundle component. For some reason the references were null. Using this code above in the constructor of my bundle, to explicitly get the services, did the trick. Thanks :)
  • Jakolcz
    Jakolcz over 10 years
    Thanks! @Reference threw me an "Resource not modifiable error". This worked!