Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

How to access an OSGI service from a servlet?

Avatar

Level 9

II have a servlet (example" localhost:4502/bin/my-servlet-here) where I would need to access an OSGI service.

I've tried several stuff I saw online but I cannot get access/reference to the OSGI service from my servlet.

Any ideas on how it can be done?

In the code servlet class below, I was debugging in my IDE (IntelliJ) and it's hanging/not responding on the line that starts with "ServiceReference reference"

Thanks

-----------

my servlet class

package com.myhost.core.servlets;

import com.myhost.core.services.MyService;

import javax.annotation.Resource;

import javax.inject.Inject;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import org.apache.felix.scr.annotations.sling.SlingServlet;

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import org.apache.sling.commons.json.JSONException;

import org.apache.sling.commons.json.JSONObject;

import org.osgi.framework.BundleContext;

import org.osgi.framework.ServiceReference;

@SlingServlet(paths = "/bin/myservlet", methods = "GET", metatype = true)

public class MyServlet extends SlingAllMethodsServlet {

    @Resource(name="BundleContext")

    private BundleContext context;

    @Override

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

               

    ServiceReference reference = context.getServiceReference(MyService.class.getName());

    MyService service = (MyService)context.getService(reference);

    response.setCharacterEncoding("UTF-8");

    response.setContentType("application/json;charset=UTF-8");

   

    // the code the populates the JSON variable has been taken out

   

    printWriter.write(jsonObject.toString());

}

---------

my service class

package com.myhost.core.services;

public interface MyService {

    String getPassword(String type);

}

---------

my service class implementation

package com.myhost.core.services.impl;

import com.myhost.core.services.MyService;

import org.apache.felix.scr.annotations.Activate;

import org.apache.felix.scr.annotations.Component;

import org.apache.felix.scr.annotations.Property;

import org.apache.felix.scr.annotations.Service;

import org.apache.sling.commons.osgi.PropertiesUtil;

import java.util.Map;

@Service

@Component(metatype = true, label = "My Service Implementation")

public class MyServiceImpl implements MyService {

    @Property(label = "property1")

    private static final String Property1 = "com.myhost.core.services.MyService.property1";

    private String property1;

    @Property(label = "property2")

    private static final String Property2 = "com.myhost.core.services.MyService.property2";

    private String property2;

    @Activate

    protected void activate(Map<String, Object> properties) {

        this.property1 = PropertiesUtil.toString(properties.get(Property1), null);

        this.property2 = PropertiesUtil.toString(properties.get(Property2), null);

    }

    @Override

    public String getProperty(int temp) {

        switch (temp) {

            case 1:

                return property1;

            case 2:

                return property2;

            default:

                return "";

        }

    }

}

3 Replies

Avatar

Level 10

It seems that you want to use R4 for this implementation..

Did you try using @Reference annotation in servlet?

@Reference

private MyService myService;

Add immediate=true in service

  1. @Component(metatype = true, label = "My Service Implementation", immediate=true

you may not need the following lines unless you have a specific requirement:

  1. @Resource(name="BundleContext"
  2.     private BundleContext context; 
  3. ServiceReference reference = context.getServiceReference(MyService.class.getName()); 
  4.     MyService service = (MyService)context.getService(reference); 

Avatar

Level 9

I did try @reference also (didn't write that in the original post) and service variable was null. But I also didn't have immediate=true. Trying your suggestion now.

Avatar

Community Advisor

If you don't want to use this service outside bundle then remove @Service   annotation from MyServiceImpl and use @Reference annotation as suggested by Gaurav.

@Reference

private MyService myService;



Arun Patidar