OSGI Services

What is a service?

An OSGi service is a java object instance, registeredinto 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 OSGi R3 specification, chapter 4.10 is highly recommended reading. Also, the javadoc for BundleContext contains lot of information.
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.
Both publishing/registering and usage of services can be restricted by using java security permissions.
Registering a very simple object as a service
Long i = new Long(20); Hashtable props = new Hashtable(); props.put("description", "This an long value"); bc.registerService(Long.class.getName(), i, props);
Note: a service can also be registered as several interfaces. In this case, the object must implement all of the interfaces.

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.
A service factory is registered in exactly the same way as a normal service, using registerService, the only difference is an indirection step before the actual service object is handed out.
The client using the service need not, and should not, care if a service is generated by a factory or by a plain object.
A simple service factory example
class LongFactory implements ServiceFactory { public Object getService(Bundle bundle, ServiceRegistration reg) { // each bundle gets a Long with it's own id return new Long(bundle.getBundleId()); } void ungetService(Bundle bundle, ServiceRegistration reg, Object service) { // nothing needed in this case } } ServiceFactory factory = new LongFactory(); bc.registerService(Long.class.getName(), factory, new Hashtable());
Note: The framework will cache generated service objects. Thus, at most one service can be generated per client bundle.

What can services be used for?

The service concept is a very general-purpose tool, but some examples are:
  • Export functionality from a bundle to other bundles
  • Import functionality from other bundles
  • Register listeners for events from other bundles
  • Expose external devices, such as UPnP devices or even hardware, to other OSGi bundles. See the Device and UPnP APIs
  • Expose java code running in OSGI to an external network, e.g. via the UPnP or SOAP protocols.
  • Bundle configuration, using the Configuration Manager

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