Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 5
If you try running the sample service package now it will print "Hello World" on your Eclipse console. If you try running
Activator.java to access HelloServiceImpl.java and compile it with the normal javac complier, it will compile. If you try to execute this bundle in an OSGi container, however, it will throw an exception.
How is the OSGi container able to hide a few classes from the .jar file while others are visible? The answer is that the OSGi container uses the Java class loader to manage class visibility. The OSGi container creates a different class loader for every bundle. The bundle can therefore access classes from
java.* packages.
HelloWorld bundle imports the com.javaworld.sample.service package so it can access classes from that package.
The bundle-level scope is a powerful feature allowing you (for instance) to safely change the HelloServiceImpl.java class without worrying that dependent code might break.
As previously mentioned, the OSGi architecture is a very good candidate for implementing service-oriented applications. It allows bundles to export services that can be consumed by other bundles without knowing anything about the exporting bundle. Taken with the ability to hide the actual service implementation class, OSGi provides a perfect combination for service-oriented applications.
In OSGi, a source bundle registers a POJO (you don't have to implement any interfaces or extend from any superclass) with the OSGi container as a service under one or more interfaces. The target bundle can then ask the OSGi container for services registered under a particular interface. Once the service is found, the target bundle binds with it and can start calling its methods. As with other OSGi concepts, a sample application will make all of this more clear.
In this section we will change the HelloService bundle so that it exports objects of the HelloServiceImpl.java class as a service. Here are the steps to set up the sample application:
MANIFEST.MF for com.javaworld.sample.HelloService to import the org.osgi.framework package.
com.javaworld.sample.service.impl.HelloServiceActivator.java as shown in Listing 7.
public class HelloServiceActivator implements BundleActivator {
ServiceRegistration helloServiceRegistration;
public void start(BundleContext context) throws Exception {
HelloService helloService = new HelloServiceImpl();
helloServiceRegistration =context.registerService(HelloService.class.getName(), helloService, null);
}
public void stop(BundleContext context) throws Exception {
helloServiceRegistration.unregister();
}
}
BundleContext.registerService() method to export the service. It takes three parameters:
String array of interface names and pass it as your first argument. In the sample code we want to export the service under the name
of HelloService interface.
HelloServiceImpl class as the service.
Dictionary object. If more than one bundle exports a service under the same interface name then the target object can use these properties
to filter out the service that it is interested in.
MANIFEST.MF file of the HelloService bundle to declare HelloServiceActivator as the bundle's activator class. To do that, simply add com.javaworld.sample.service.impl.HelloServiceActivator as the value of the Bundle-Activator header in your MANIFEST.MF file.
Now the HelloService bundle is ready to export objects of the HelloServiceImpl class. When the OSGi container starts the HelloService bundle it will pass control to HelloServiceActivator.java, which will register an object of HelloServiceImpl as a service. The next step is to create the service consumer.
In this section we will change the HelloWorld bundle developed in the last section so that it acts as a consumer of the HelloService service. The main thing you need to do is change the Activator.java for the HelloWorld bundle as shown in Listing 8.
public class Activator implements BundleActivator {
ServiceReference helloServiceReference;
public void start(BundleContext context) throws Exception {
System.out.println("Hello World!!");
helloServiceReference= context.getServiceReference(HelloService.class.getName());
HelloService helloService =(HelloService)context.getService(helloServiceReference);
System.out.println(helloService.sayHello());
}
public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World!!");
context.ungetService(helloServiceReference);
}
}
The BundleContext.getServiceReference() method returns a ServiceReference object for a service registered under the HelloService interface. If multiple such services exist, the service with the highest ranking (as specified in its Constants.SERVICE_RANKING property) is returned. Once you have the object of ServiceReference you can call its BundleContext.getService() method to get the actual service object.
You can run this sample the same way you would execute any bundle, by clicking Run --> Run Simply make sure that both the HelloWorld and HelloService bundles are checked in as plugins. When you start the HelloService bundle, you will see the message "Inside HelloServiceImple.sayHello()" printed from the HelloServiceImpl.sayHello() method.
OSGi open source containers
More
Archived Discussions (Read only)