Issue
In Adobe Experience Manager (AEM) projects developers are working a lot in services, filters, servlets and handlers. All of these classes are OSGi components and services using the Felix SCR annotations or the newer OSGi DS annotations. But sometimes you need an OSGi service or the BundleContext also in non OSGi / DS controlled class
In Adobe Experience Manager (AEM) projects developers are working a lot in services, filters, servlets and handlers. All of these classes are OSGi components and services using the Felix SCR annotations or the newer OSGi DS annotations. But sometimes you need an OSGi service or the BundleContext also in non OSGi / DS controlled class
Solution
You can use the OSGi FrameworkUtil [1] to get the reference to the bundle context from any object. The code below shows how to get reference to the BundleContext and the service.
Most of the time, you have the SlingHttpServletRequest ready to pass:
Or you just use the class that was loaded over a bundle classloader.
[1] https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/FrameworkUtil.html
You can use the OSGi FrameworkUtil [1] to get the reference to the bundle context from any object. The code below shows how to get reference to the BundleContext and the service.
Most of the time, you have the SlingHttpServletRequest ready to pass:
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import java.util.Objects;
public class ServiceUtils {
/**
* Gets the service from the current bundle context.
* Return null if something goes wrong.
*
* @param <T> the generic type
* @param request the request
* @param type the type
* @return the service
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> T getService(SlingHttpServletRequest request, Class<T> type) {
SlingBindings bindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName());
if (bindings != null) {
SlingScriptHelper sling = bindings.getSling();
return Objects.isNull(sling) ? null : sling.getService(type);
} else {
BundleContext bundleContext = FrameworkUtil.getBundle(type).getBundleContext();
ServiceReference settingsRef = bundleContext.getServiceReference(type.getName());
return (T) bundleContext.getService(settingsRef);
}
}
}
Or you just use the class that was loaded over a bundle classloader.
package com.sanitas.aem.core.utils;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
public class ServiceUtils {
/**
* Gets the service from the current bundle context.
* Return null if something goes wrong.
*
* @param <T> the class that was loaded over a bundle classloader.
* @param type the service type.
* @return the service instance.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> T getService(Class clazz, Class<T> type) {
Bundle currentBundle = FrameworkUtil.getBundle(clazz);
if (currentBundle == null) {
return null;
}
BundleContext bundleContext = currentBundle.getBundleContext();
if (bundleContext == null) {
return null;
}
ServiceReference<T> serviceReference = bundleContext.getServiceReference(type);
if (serviceReference == null) {
return null;
}
T service = bundleContext.getService(serviceReference);
if (service == null) {
return null;
}
return service;
}
}
[1] https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/FrameworkUtil.html
No comments:
Post a Comment
If you have any doubts or questions, please let us know.