Finding the right OSGi services using the objectclass property

November 30, 2012 | 2 min Read

Recently I wanted to use the good old ServiceTracker to get access to OSGi services registered under a specific interface and matching a given filter. I was surprised to discover that there is no constructor for the ServiceTracker that allows the specification of a class name and a filter.

A quick look into the OSGi specification revealed: the list of the service interfaces is made available by the OSGi framework as the service property objectClass. Using this property, the interface can be part of the filter:

   BundleContext bundleContext = ...
   String filterString = "(objectClass=com.eclipsesource.MyInterface)";
   Filter filter = bundleContext.createFilter(filterString);
   ServiceTracker tracker = new ServiceTracker(bundleContext, filter, null);

Here is a cleaner alternative for specifying the filter string above:

   String filterString = "(" + Constants.OBJECTCLASS + 
                         "=" + MyInterface.class.getName() + ")";

There is actually a bunch of service properties that are set by the framework or at least have predefined semantics. See the OSGi specification for a complete table of standard service properties defined by the framework, or have a look at the interface org.osgi.framework.Constants for the properties’ keys.

Another interesting side note about the objectClass property is the fact that its value is actually a String array of the interfaces the service is registered for. This even allows you to find matches for several interfaces at once, using only one filter string:

   String filterString = "(&(" + Constants.OBJECTCLASS + 
                         "=" + MyInterface.class.getName() + ")" +
                         "(" + Constants.OBJECTCLASS + 
                         "=" + MyOtherInterface.class.getName() + "))";

The objectClass service property allows you to formulate complex filters for your services that go beyond what the standard OSGi API can offer.