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);
What is the difference between @Service and @Component?
What if I don’t put @Service or @Component in the above example?
LikeLike
Hi Sanjana, The question which you are asking is in fact the most fundamental one and it is often asked in interviews. I have already answered this question in detail at https://hashimkhan.in/ask-me/ Q1. May you please refer that.
Hopefully that will clarify your doubt.
Regards
Hashim
LikeLike
Hi Hashim,
I did not find the answer to the difference between service and component in the above link.
Can you please post the link where answer is available.
LikeLiked by 1 person
Please check the link https://hashimkhan.in/ask-me/comment-page-1/#comments
With @Service you can use the object with the same bundle and across bundles with dependency injection. However with @Component the class is available in the same bundle only.
LikeLiked by 1 person
Hi Hashim, how can we access the class in same bundle by using @Component only? Is it something by declaring it in import/export?
LikeLike
Yes, @Component is used to declare a class an OSGi component. Within a bundle you can directly use the Class in another class by using import statements.
LikeLike
Hello Sir,
Can you please explain how can i call osgi bundle classes in my java code
LikeLike
Are your OSGi bundle classes OSGi Components? You can use them as normal java classes too by making an import statement. Please elaborate more what is the exact quesiton
LikeLiked by 2 people
Hi
I could not find the answer to the difference between service and bundle in the link”https://hashimkhan.in/ask-me”
Can you please post the link again ?
LikeLike
Please check the link https://hashimkhan.in/ask-me/comment-page-1/#comments
LikeLike
What is difference between @service class and plain java with in the bundle ? What is the benefit if we declare as @service ?
LikeLike
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.
LikeLike
Hi Hasim,
Which attribute of the Component annotation should be used to define a service factory?
LikeLike
That should be configurationFactory = true Read more here http://www.tothenew.com/blog/creating-osgi-factory-configurations-in-aem/
LikeLiked by 1 person
Hi Hashim,
Should I check this under services or components tab in felix console?
LikeLike
Hi,
Every Service is also a component, so you should be able to check it at both places if its a Service.
LikeLike
Hi,
Can you please share one example of service factory and it’s usages?
LikeLike
Hi, You can read this good post http://www.tothenew.com/blog/creating-osgi-factory-configurations-in-aem/
and check this example on how to use it https://techrevel.blog/2017/04/12/felix-configuration-factory/
LikeLike
Hello. Simple Help! Can u help in solutions to this..
I created exactly https://helpx.adobe.com/experience-manager/using/first-osgi.html. In JSP the AEM,SLing code NOT work. Only HTMl works.
LikeLike
Hi, Is your service active? What is the error coming up in logs?
What code snippet are you using in JSP?
LikeLike
Error resolved: @Component(metatype = true , immediate = true) to change from registered to active state and Unbind the services from newly updated jars to use methods of active service.
Thanks!
LikeLiked by 1 person
Can we create an OSGi service without using @service annotation?
LikeLike
Yes with AEM6.2 there is a new concept of OSGi Declarative services – Read more about this-
http://www.nateyolles.com/blog/2017/05/osgi-declarative-services-annotations-in-aem
LikeLike