Friday

Alternative on Building OSGi service: build using iPOJO

Continuing from a previous post on creating OSGi services, this posting, is making thinks more adaptable. The adaptation key here, is in iPOJO.  iPOJO stands for injected POJO. It’s a component model from Apache on top of OSGi. It is very flexible, extensible and easy to adapt as already mentioned. It is a try to remove the overhead of developer’s handling services in OSGi. So, as before, let’s build a simple service using iPOJO and consume it.

OSGi is about modularizing your application. In this demo, we will have three projects (or three bundles) that will be deployed on Apache Felix. The needed ingredients are:

  1. Bnd tool from aQute

Problem Statement

The problem is very simple: Our service is a simple OSGi service that will display the string “Hi There!”.

Getting Started

Like any OSGi service, our service is represented as an interface:

package hi.service;
public interface HiService {
public String sayHi();
}


This will be our first project or first bundle. The bundle will have just the interface. Please note that you will have to export hi.service package when building the bundle. To make this task easy, use the bnd tool to create the jar. I have used Ant script to compile and package the projects. Once bundle is ready, you will use it as a dependency library for compiling other projects.



 



Service Implementation





The next step is to implement our service. We will create a new project with previous projects jar file as a dependency. The service implementation is also POJO and there is no mention of OSGi service in the code. Let’s have a look at our implementation:



package hi.component;
import hi.service.HiService;
public class HiComponent implements HiService {
String message = "Hi There!";
public String sayHi() {
return message;
}
}


Now we define that we have a iPOJO component. This is done through a xml that is placed along with the project. The xml defines that, we have a component of the class hi.component.HiComponent. The example below is a very simple one, you can have call backs, properties set etc in this xml using different xml elements.



<ipojo>
<component classname="hi.component.HiComponent">
<provides/>
</component>
<instance component="hi.component.HiComponent"/>
</ipojo>


We will compile this project into another bundle that will be deployed in the runtime.



 



Using the Service



This is the final project. This project will be consuming the service we created above. The client can be a POJO or a Activator class. Like the service implementation code, we do not code for a service. Instead we go about and code as if the implementation is available to us. iPOJO framework would take care of the rest. Here is our "Hi there!" client:



package hi.client;
import hi.service.HiService;

public class HiClient {

private HiService m_hi;

public HiClient() {
super();
System.out.println("Hi There Client constructor...");
}

public void start() {
System.out.println("Starting client...");
System.out.println("Service: " + m_hi.sayHi());
}

public void stop() {
System.out.println("Stoping client...");
}
}


I have some sys outs to see how our client work. Just like the service project, we have a xml that will define what is the required service, callback functions etc. Have a look at the xml:



<ipojo>
<component classname="hi.client.HiClient">
<requires field="m_hi"/>
<callback transition="validate" method="start"/>
<callback transition="invalidate" method="stop"/>
</component>
<instance component="hi.client.HiClient"/>
</ipojo>


The xml specifies that HiClient requires m_hi to execute. m_hi is a instance of our service. So as long as the service is not available, the HiClient component does not get executed. The callback xml elements specify which methods to execute when the state of the component changes.

Once compiling and packaging of this project is done, we are ready to deploy our example into a runtime and see it working. When you have Felix and iPOJO framework downloaded, you have to configure Felix to load the bundles when it’s started.


Felix configurations are placed in config.properties under conf folder.You will have to modify the entires for felix.auto.start.1 variable. Here is how it looked like after I modified:



felix.auto.start.1= \
file:bundle/org.apache.felix.shell-1.0.1.jar \
file:bundle/org.apache.felix.shell.tui-1.0.1.jar \
file:bundle/org.apache.felix.bundlerepository-1.0.3.jar \
file:bundle/org.apache.felix.ipojo-1.0.0.jar \
file:bundle/hi.service.jar \
file:bundle/hi.component.jar \
file:bundle/hi.client.jar


I have put all my jars in felix/bundle folder. You may place them in different location but you must specify the correct paths above.

We are ready now. Run your felix runtime to see the results!

No comments: