This is the first post of the Dynamokos series. This series explores how to build dynamic distributed web applications with OSGi step by step.
Inside this post
In this post, we will show how to:
- Use Apache CXF DOSGi to expose an OSGi service as a web service
- Use Apache CXF DOSGi to import the remote service in another OSGi framework
- Consume the imported service
The code of the post is available from the Dynamokos Google Project.
This post is very similar to the iPOJO / DOSGi tutorial.
Architecture

The application uses Apache Felix as OSGi implementation. Two instances of Felix are required, one for the oracle and one for the web part.
Apache Felix iPOJO is used as component model because of its simplicity. It allows for a very clean way to export OSGi services remotely thanks to ‘property propagation’.
Of course, we use Apache CXF DOSGi. This is an implementation of OSGi Distributed Services. This (big) bundle is deployed on both frameworks as it allows both the exportation and the importation (note that it exist a multi-bundle distribution too).
Finally, we use OPS4J Pax Web as HTTP Service implementation. DOSGi embeds it, so we don’t need to deploy it separately.
Implementing the Oracle
The application relies on a very advanced Prediction service. The service interface is quite simple and just allows querying the Oracle. Possible answers are those listed in the interface.
public interface Prediction { /** * Possible answers. */ public String[] predictions = new String[] { // .... }; public String getPrediction(); public String getPrediction(String question); }
The Oracle component implements the Prediction service. I will not unveil the Oracle prediction algorithm here (you can just look at the code). The only interesting things are:
@Component(propagation=true) @Provides public class Oracle implements Prediction { // Oracle secret ... }
The @Component annotation declares an iPOJO Component Type. It also implements the Prediction service (@Provides will mange the service exposition). The propagation attribute (set to true) enables property propagation. This means that configuration properties are pushed/propagate to the provided service.
Note that this implementation DOES NOT have any
- OSGi code
- Code related to distribution
However, this just declares a component type, not an instance. The instance declaration is made in an XML file (iPOJO also offers other ways, but it’s not the topic of this post):
As you can see, I add a couple of properties in the instance configuration. Thanks to the propagation, those properties will be automatically published in the OSGi Service registration (Prediction service).
DOSGi tracks those properties. Once found, it exposed the OSGi service as a remote service according to the given properties. Here, it will be a web service, and every exposed service interface will be remotely accessible. This simple mechanism is very powerful, as it does not impact the service implementation, and allows an administrator to expose services dynamically.
Launching the Oracle
So lets have a look at the Oracle in action.
First, download the dynamokos-runtime from here. Then, unzip it and go in the runtime folder (with a terminal). In this post, I do not explain how to compile it, instruction are also given in the project documentation.
The folder contains preconfigured versions of Felix. To launch the oracle platform, just execute:
java \ -Dfelix.config.properties=file:./conf/oracle-dosgi.properties \ -jar bin/felix.jar cache/oracle-dosgi
This launches Felix, prints a lot of stuff (DOSGi is a little bit verbose) and deploys required bundles:
ps START LEVEL 1 ID State Level Name [ 0] [Active] [ 0] System Bundle (2.0.0) [ 1] [Active] [ 1] Distributed OSGi ... (1.1.0.SNAPSHOT) [ 2] [Active] [ 1] Apache Felix Bundle Repository (1.4.1) [ 3] [Active] [ 1] Apache Felix File Install (1.2.0) [ 4] [Active] [ 1] Apache Felix iPOJO (1.4.0) [ 5] [Active] [ 1] Apache Felix iPOJO Arch Command (1.4.0) [ 6] [Active] [ 1] Apache Felix Shell Service (1.4.0) [ 7] [Active] [ 1] Apache Felix Shell TUI (1.4.0) [ 8] [Active] [ 1] OSGi R4 Compendium Bundle (4.1.0) [ 9] [Active] [ 1] Prediction Service Interface (0.0.1.SNAPSHOT) [ 10] [Active] [ 1] Oracle (0.0.1.SNAPSHOT)
Note: be sure that the port 9090 is available as well as the 8085.
To check that everything works, open a browser to http://localhost:9090/oracle?wsdl.
You should get the Prediction service WSDL.

Importing the oracle
It’s time to import the prediction service in the other framework. As already said, DOSGi also manages this aspect which is what this first post is all about.
So, to import a remote service with DOSGi, you need to create a bundle containing OSGI-INF/remote-services/remote-services.xml
* org.apache.cxf.ws http://localhost:9090/oracle
This file just tells DOSGi to import our Oracle remote service. Note that the service interface and the location are given. Obviously, the bundle exporting the Prediction service interface has to be deployed on this OSGi gateway too.
When DOSGi discovers such files, it creates a proxy and exposes a corresponding local OSGi service for the given remote service.
In Dynamokos, I created an almost empty bundle containing just this one file. Despite it is also possible to embed this file in just any bundle, I prefer separating the distribution system from my business code. Clear separations are always good.
Consuming the remote service
Now that the Oracle is accessible from the second platform (published as an OSGi service), we just need to use it. In the Dynamokos application, a simple servlet uses the Oracle. This servlet allows a web page to display predictions.
@Component public class OracleServlet extends HttpServlet { /** * iPOJO injects the HTTP Service in this member. */ @Requires private HttpService http; /** * iPOJO injected the Prediction service in this member. */ @Requires private Prediction oracle; @Validate public void start() throws ServletException, NamespaceException { // Expose itself http.registerServlet("/oracle", this, null, null); // Expose the web page http.registerResources("/dynamokos", "web", null); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String q = req.getParameter("question"); if (q == null || q.length() == 0) { resp.getOutputStream().print(oracle.getPrediction()); } else { resp.getOutputStream().print(oracle.getPrediction(q)); } } }
This servlet is quite simple. It is an iPOJO component requiring both the HTTP Service and the Prediction service. When both are available, the start method is called. This method published the web resources (itself, and the web page). When the web page interacts with the servlet, it just uses the oracle member to use the real oracle. No synchronization, no OSGi burden, just simple…
The web page code is also provided in the project.
Trying the ultimate oracle
Finally, it’s time to start the second gateway and to get some predictions.
With another terminal, go back to the runtime folder. Then executes the following command:
java \ -Dfelix.config.properties=file:./conf/client-dosgi.properties \ -jar bin/felix.jar cache/client-dosgi
This also starts Felix with the adequate bundles:
ps START LEVEL 1 ID State Level Name [ 0] [Active] [ 0] System Bundle (2.0.0) [ 1] [Active] [ 1] Distributed OSGi ... (1.1.0.SNAPSHOT) [ 2] [Active] [ 1] Apache Felix Bundle Repository (1.4.1) [ 3] [Active] [ 1] Apache Felix File Install (1.2.0) [ 4] [Active] [ 1] Apache Felix iPOJO (1.4.0) [ 5] [Active] [ 1] Apache Felix iPOJO Arch Command (1.4.0) [ 6] [Active] [ 1] Apache Felix Shell Service (1.4.0) [ 7] [Active] [ 1] Apache Felix Shell TUI (1.4.0) [ 8] [Active] [ 1] OSGi R4 Compendium Bundle (4.1.0) [ 9] [Active] [ 1] Oracle Importer (0.0.1.SNAPSHOT) [ 10] [Active] [ 1] Client UI (0.0.1.SNAPSHOT) [ 11] [Active] [ 1] Prediction Service Interface (0.0.1.SNAPSHOT)
Once launched, open a browser to http://localhost:8080/dynamokos/index.html
And ask the Oracle.
Note : Check that the port 8080 is available.

Issues and Conclusion
Despite great, this demo has a small issue. Let’s try to stop the oracle platform:
shutdown
Then, try to re-ask the Oracle, the answer is now: “Oracle temporary unavailable.”

In fact, configured like that, DOSGi is not dynamic. So the Prediction service is still published, and subsequently, for local bundles, still usable!
Worse, now shutdown the client platform, restart the platform (without restarting the oracle platform), reload the page and re-ask something. You will get an “Oracle Temporary Unavailable” message. In fact, DOSGi does not check the availability of the service at all — it makes the assumption that the service is always there.
This is fine for static web services, but coming from a dynamic OSGi perspective, we really would like to go further and have the (local) service only be available if the real (remote) service can be reached. Of course this is possible as we will show in the second post of this series by adding a discovery protocol in order to track the availability of the oracle service. So stay tuned!
If you have questions, feel free to post a comment on this post or to contact us.
Thanks u for this post. very interesting info. regards
Really great info. I am very glad I found this blog post
There are actually lots of details like that to take into consideration. That could be a great point to bring up. I offer the thoughts above as common inspiration but clearly there are questions just like the one you bring up where crucial thing shall be working in trustworthy good faith. I don?t know if finest practices have emerged around issues like that, but I’m sure that your job is clearly identified as a good game. Both girls and boys feel the impact of just a second’s pleasure, for the rest of their lives.
Hi there could I use some of the insight from this entry if I reference you with a link back to your site?