• Articles about computing
• Articles about software development
• Apache integration software
Implementing an Apache Karaf route in an OSGi Java bundle
from the ground up
This article describes how to install and manage an Apache Camel route
as an OSGi bundle within the Apache Karaf container. Like all the
articles in this series, it proceeds from first principles, and uses
no sophisticated software tools or IDEs. However, it builds on
the principles described in my articles on
Creating OSGi bundles and
Creating a Camel route, and I assume that the reader is familiar
with the material in those articles. In particular, I won't describe again
what an OSGi bundle is, nor
how to obtain and set up Karaf, nor the fundamental
principles of Camel routing in Java — the other
articles deal with these topics. Here I assume that Camel is
installed, and Karaf is installed and running.
In this article I use the same file-copy Camel route as in my
Camel article, but with some extra processing, just to demonstrate
an additional feature of Camel. What we'll end up is a bundle that
can be deployed on Karaf, and which will copy files from one
directory to another, inserting a timestamp at the top of each one.
Not a very impressive feat, of course, but it does demonstrate
Karaf/Camel integration in a self-contained way.
The bundle created in this article should work with Apache ServiceMix
as well as Karaf; in fact, it should be easier to set up,
as ServiceMix has the
necessary Camel bits pre-installed. However, at the time I wrote this,
the latest stable version of ServiceMix had Camel components that were
to early to have all the necessary OSGi support, so installing on ServiceMix
would have meant removing a heap of stuff and installing newer versions. This
situation might well have improved by the time you read this.
Setting up Karaf with Camel support
At the time of writing, setting up Karaf so that we can use the
recommended form of
CamelContext (see below) is a
bit fiddly. We start by installing the basic Camel support as
karaf@root> features:chooseurl camel 2.12.1
karaf@root> features:install camel
Be aware that installing
camel can take a while, and
you don't get
a lot of progress indication. Next we need to install support for
Camel OSGi integration, but (so far as I can tell) this can't be
installed as feature; we need to get it explicitly from the respository.
In fact, before we can do even that, we need to install the
eventadmin bundle that the OSGi support depends on, and
that needs to be done manually.
Download the bundle
install it using
karaf@root> osgi:install file:/path/to/org.apache.felix.eventadmin-1.3.2.jar
Now we can install OSGi support from the repository:
karaf@root> osgi:install -s mvn:org.apache.camel/camel-core-osgi/2.12.1
[Update, May 2014: it seems now to be possible to install Camel OSGi
support from the repository:
osgi:install -s mvn:org.apache.camel/camel-osgi/1.5.0.
So you shouldn't need to download the above-mentioned bits separately.]
If Camel support is properly installed, the output of
osgi:list should show at least the following bundles, and
all in the Active state (you might have to start them manually with
[ 54] [Active ] [ ] [ 80] camel-core (2.12.1)
[ 55] [Active ] [ ] [ 80] camel-core-osgi (2.12.1)
[ 66] [Active ] [ ] [ 80] Apache Felix EventAdmin (1.3.2)
In practice you might see additional modules, but they aren't necessary
for this example. The bundle
useful for managing Camel routes defined in, for example, XML files, but
it isn't necessary (or even functional) for Java routes.
Building the Camel route bundle
In this section I'll describe how to implement a Camel route in Java,
inside an OSGi bundle. The bundle requires only two source files:
one Java class and a manifest. The Java class will play the role of the
bundle activator (that is, it will provide the
stop() methods for management by the container), and
the route processor — what little processing is involved. In a real application
these two disparate tasks would probably be better separated into different
Setting up the workspace
I'm assuming that there is a directory structure like this:
Activator.java # This is the Java source for the bundle
classes # Compiled code will go here
MANIFEST.MF # This is the bundle manifest
The source code bundle is available from the Download section at the
end of this article, and will create the necessary directory structure
Coding the route
The source code for the Camel route is not very different from the
simple file copier in my Camel article.
I hope that, with comments, it's reasonably self-explanatory.
public class Activator implements BundleActivator
private CamelContext camelContext = null;
public void start(BundleContext bundleContext) throws Exception
System.out.println ("File copier started");
camelContext = new OsgiDefaultCamelContext(bundleContext);
public void configure()
Processor myProcessor = new Processor()
public void process (Exchange exchange)
System.out.println ("Processing file: " + exchange);
Message in = exchange.getIn();
in.setBody (new Date().toString() + "\n\n"
public void stop(BundleContext bundleContext) throws Exception
System.out.println("File copier stopped");
The bundle will copy any files that arrive in
to /tmp/out, after prepending a timestamp. Of course
you're free to change these directories to ones that are more suitable
for your system. The directories will be created at runtime if they
do not already exist.
Writing the manifest
Here is the complete manifest for this bundle.
Bundle-Name: Kevin's Karaf Camel Test
Bundle-Vendor: Kevin Boone
org.apache.camel, org.apache.camel.impl, org.apache.camel.builder,
The Camel support bundle in Karaf is divided into a number of different
Java packages, each of which must be included individually. If you
don't have a clever IDE tool to tell you which imports you need,
you can proceed with a mixture of
find-class in the
Karaf console, intuition, Google, and luck. The last import
org.apache.camel.core.osgi is perhaps the least obvious;
this package provides the
Building the bundle
We need to compile the code and then build a JAR file including the
manifest. Here's how to do this at the command line:
$ javac -d target/classes -classpath /path/to/karaf/lib/karaf.jar:\
$ jar cfm karafcameltest.jar etc/MANIFEST.MF -C target/classes .
Note that the first command is intended to be one long line. As always,
you'll need to replace the
/path/to prefixes with the actual
locations of Karaf and Camel on your system. The JAR
camel-core-osgi is needed specifically to provide the
All being well, you should end up with a bundle
karafkameltest.jar in the current directory.
Testing the bundle
Now it's just a case of installing the bundle in Karaf, and starting it.
karaf@root> osgi:install file:/path/to/karafcameltest/karafcameltest.jar
Bundle ID: 74
karaf@root> start 74
File copier started
Then try copying some files into the
and see what happens. The Bundle produces output to
each time it processes a file, and this output should appear on the console.
In case of problems, check for errors in the log at
As with any other bundle, you can stop the route bundle using
I hope it is clear from this example that there's not a lot more to
building a Camel route into an OSGi bundle than there is to running
the Camel routing engine on its own. We do have to take care to
start and stop the route when the bundle is started and stopped, but
that's about all there is to it.
Source code bundle