Service


What is a Service?

An OSGi service is a java object instance, registered into an OSGi framework with a set of properties. Any java object can be registered as a service, but typically it implements a well-known interface.
The client of a service is always an OSGi bundle, i.e. a piece of java code possible to start via the BundleActivator interface.
Each bundle may register zero or more services. Each bundle may also use zero or more services. There exists no limit on the number of services, more than the ones given by memory limits or java security permissions.


What is a Service Factory?

An OSGi service factory is a special class ServiceFactory, which can create individual instances of service objects for different bundles. Sometimes a service needs to be differently configured depending on which bundle uses the service. For example, the log service needs to be able to print the logging bundle’s id, otherwise the log would be hard to read.

Generally, services is the preferred method bundles should use to communicate between each other.


Sample OSGi Service Implementation:

  • Interface
public interface SampleService {
    public String helloWorld();
    public String getName(String path) throws LoginException;
}
  • Implementaion

@Component(
        label = "Sample Service Impl",
        description = "Sample Description",
        metatype = true,
        immediate = false)
@Properties({
        @Property(
                label = "SampleVendor",
                name = "service.vendor",
                value = "SampleVendor",
                propertyPrivate = true
        )
})
@Service
public class SampleServiceImpl implements SampleService {
    
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private static final boolean DEFAULT_ENABLED = false;
    private boolean enabled = DEFAULT_ENABLED;
    
    @Property(label = "Service Enable/Disable", description = "Enables/Disables the service without nullifying service reference objects. This enable/disabling must be implemented in all public methods of this service.", boolValue = DEFAULT_ENABLED)
    
    public static final String PROP_ENABLED = "prop.enabled";

    /* OSGi Service References */
    @Reference
    private ResourceResolverFactory resourceResolverFactory;

    /*** Service Methods ***/
    @Override
    public String helloWorld() {
        if (!this.enabled) {
            return "Service has been disabled";
        }
        return "Hello World!";
    }

    @Override
    public String getName(final String path) throws LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
        Resource resource = resourceResolver.resolve(path);
        if(resource == null) {
            return null;
        }
        return resource.getName();
    }

    /*** OSGi Component Methods ***/
    @Activate
    protected void activate(final ComponentContext componentContext) throws Exception {
        final Map<String, String> properties = (Map<String, String>) componentContext.getProperties();
        configure(properties);
    }

    @Deactivate
    protected void deactivate(ComponentContext ctx) {
        this.enabled = false;
    }

    protected void configure(final Map<String, String> properties) {
        // Global Service Enabled/Disable Setting
        this.enabled = PropertiesUtil.toBoolean(properties.get(PROP_ENABLED), DEFAULT_ENABLED);
    }
}


How are services accessed?

There are a few ways by which you may be able to use your defined Service:

  • Use SCR annotations to let SCR inject the service in your component:
@Reference
   private SlingRepository repository;
  • Use Bundle Context to get the service in your Java/Jsp file
BundleContext bundleContext = FrameworkUtil.getBundle(MyClass.class).getBundleContext();
ServiceReference factoryRef = bundleContext.getServiceReference(ResourceResolverFactory.class.getName());
ResourceResolverFactory resolverFactory = (ResourceResolverFactory) bundleContext.getService(factoryRef);
/*Always make sure to use a null check whenever getService is used*/
  • Use sling.getService() method
  SampleService service=sling.getService(SampleService.class);

Read More

23 thoughts on “Service

    • Hi, Whenever you declare a class as a @Service , it will have only one instance throughout which you can reference using Dependency Injection (@Reference annotation) . This service class instance you can use within bundles too. However if you use @Component , you can start and stop that Component , in addition to all the properties of a normal class. While if you use plain java class, you have to create instances everytime you need to use that Class.

      Like

Leave a reply to Bharat Agrawal Cancel reply