Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Adobe Summit 2023 [19th to 23rd March, Las Vegas and Virtual] | Complete AEM Session & Lab list

How to access an OSGI service from a servlet?

Avatar

Level 8

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

Community Advisor

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 8

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;

The ultimate experience is back.

Join us in Vegas to build skills, learn from the world's top brands, and be inspired.

Register Now