You can create an object and register it as an OSGi service
for use by third-party features.
About this task
By using plain old Java code, you can create an object,
and then register it as a service using the BundleContext class.
Because the code has to run, you typically register the object in
a BundleActivator interface. When you register the
object, you can specify what interfaces it provides, and supply a
property map. A ServiceRegistration object is returned;
if necessary, you can use the ServiceRegistration object
to change the properties at any time. When the service is completed,
you use the ServiceRegistration object to unregister
the service.
To obtain a service, you query the BundleContext for
a service that implements a required interface and, optionally, supply
an LDAP-syntax filter to match the service properties. Depending on
the method you call, you can retrieve the best match or all the matches.
You can then use the returned ServiceReference that
provides the properties to do further matching in your code. You can
use the ServiceReference to get the actual service
object. When you have finished using the service, you use the BundleContext to
release the service.
- Declare the service interface by adding the following code
in your bundle.
package com.ibm.foo.simple;
/**
* Our multifunctional sample interface
*/
public interface Foo
{
}
- Specify the implementation code of the interface.
package com.ibm.foo.simple;
/**
* The implementation of the Foo interface
*/
public class FooImpl implements Foo
{
public FooImpl()
{
}
public FooImpl(String vendor)
{
}
/**
* used by the ServiceFactory implementation.
*/
public void destroy() {
}
}
- Use the BundleContext to register the
service, modify the service properties, and unregister the service
directly in your code.
import java.util.Dictionary;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* Registers and unregsiters a Foo service directly,
* and shows how to modify the service properties in code.
*/
public class FooController
{
private final BundleContext bundleContext;
private ServiceRegistration<Foo> sr;
public FooController( BundleContext bundleContext )
{
this.bundleContext = bundleContext;
}
public void register(Dictionary<String, Object> serviceProperties) {
Foo foo = new FooImpl();
//typed service registration with one interface
sr = bundleContext.registerService( Foo.class, foo, serviceProperties );
//or
//untyped service registration with one interface
sr = (ServiceRegistration<Foo>)bundleContext.registerService(
Foo.class.getName(), foo, serviceProperties );
//or
//untyped service registration with more than one interface (or class)
sr = (ServiceRegistration<Foo>)bundleContext.registerService(new String[] {
Foo.class.getName(), FooImpl.class.getName()}, foo, serviceProperties );
}
public void modifyFoo(Dictionary<String, Object> serviceProperties) {
//with the service registration you can modify the service properties at any time
sr.setProperties( serviceProperties );
}
public void unregisterFoo() {
//when you are done unregister the service using the service registration
sr.unregister();
}
}
- Obtain and return the service from another class:
package com.ibm.foo.simple;
import java.util.Collection;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
/**
* A simple Foo client that directly obtains the Foo service and returns it when done.
*/
public class FooUser
{
private final BundleContext bundleContext;
public FooUser( BundleContext bundleContext )
{
this.bundleContext = bundleContext;
}
/**
* assume there's only one Foo
*/
public void useFooSimple() {
ServiceReference<Foo> sr = bundleContext.getServiceReference( Foo.class );
String[] propertyKeys = sr.getPropertyKeys();
for (String key: propertyKeys) {
Object prop = sr.getProperty( key );
//think about whether this is the Foo we want....
}
Foo foo = bundleContext.getService( sr );
try {
//use foo
} finally {
//we're done
bundleContext.ungetService( sr );
}
}
/**
* Use a filter to select a particular Foo. Note we get a collection back and have to pick one.
* @throws InvalidSyntaxException
*/
public void useFooFilter() throws InvalidSyntaxException {
Collection<ServiceReference<Foo>> srs = bundleContext.getServiceReferences(
Foo.class, "(&(service.vendor=IBM)(id='myFoo')" );
ServiceReference<Foo> sr = srs.iterator().next();
String[] propertyKeys = sr.getPropertyKeys();
for (String key: propertyKeys) {
Object prop = sr.getProperty( key );
//think about whether this is the Foo we want....
}
Foo foo = bundleContext.getService( sr );
try {
//use foo
} finally {
//we're done
bundleContext.ungetService( sr );
}
}
}