Web service in OSGi bundle

In this short tutorial we will create OSGi bundle that will expose web service using CXF library. Like it or not, but the project will be created with usage of Maven utility. Also, this example will be using Spring Dynamic Modules.


Let us start with creating an empty project. We will do it using archetype:generate:

mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.0 \
-DgroupId=com.lukaszbaran.simpleosgi.ws \
-DartifactId=osgi-simple-ws -Dversion=1.0

After execution of this command, Maven should generate project structure. Delete the classes AppMain and AppTest. To make the project simpler to edit, generate Eclipse project files:

mvn eclipse:eclipse

Code & configuration

The next step is to create the interface and its implementation (don’t forget about packages as well):

 // ICalculator.java
 package com.lukaszbaran.simpleosgi.ws;
 import javax.jws.WebService;
 public interface ICalculator {
    int add(int a, int b);
    int sub(int a, int b);

Service implementation (CalculatorImpl.java) is created in com.lukaszbaran.simpleosgi.ws.impl package:

// CalculatorImpl.java
package com.lukaszbaran.simpleosgi.ws.impl;
public class CalculatorImpl implements ICalculator {
	public int add(int a, int b) {
		return a + b;
	public int sub(int a, int b) {
		return a - b;

Since the project is going to use Spring Dynamic Modules, it is necessary to create beans.xml file in src / main / resources / META-INF / spring / beans.xml path. The file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
	<import resource="classpath:META-INF/cxf/cxf.xml"/>
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
	<import resource="classpath:META-INF/cxf/cxf-extension-http.xml"/>
	<import resource="classpath:META-INF/cxf/osgi/cxf-extension-osgi.xml"/>

This file defines the address of our end-point and and points the class which implements service interface.


The next step is to create pom.xml file that will be used to build our project (of course, if you were doing this tutorial from the beginning, the only thing you need to do is to copy build section from the following XML into your POM).

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

As you can see, in the code above we configured maven-bundle-plugin, so that it would use configuration from osgi.bnd file.  It should be created in the same directory as pom.xml file:

Import-Package: javax.jws, javax.wsdl, META-INF.cxf, META-INF.cxf.osgi, org.apache.cxf.bus, org.apache.cxf.bus.spring, org.apache.cxf.bus.resource, org.apache.cxf.configuration.spring, org.apache.cxf.resource, org.apache.servicemix.cxf.transport.http_osgi, org.springframework.beans.factory.config 

Private-Package: com.lukaszbaran.simpleosgi.ws.*

Require-Bundle: org.apache.cxf.cxf-bundle

Compilation & installation

The project should be compiled by executing:

mvn clean package

If everything has been done correctly, the bundle should be now in the target directory. To make our bundle running in OSGi environment (in our case it would be Fuse ESB) we should take care of installing cxf-osgi feature (feature is simply a pack of bundles). In Fuse ESB we do it using the following command:

features install cxf-osgi

Note: if you do not do this you may get some strange exceptions like this one:

 Unresolved constraint in bundle 154:package;

Now we can install our bundle in the container (e.g. by copying to the container’s deploy directory). Service may be accessed by opening URL: http://localhost:8080/cxf/calculator?wsdl (assuming the default configuration).