Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.

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