Apache Karaf is a good platform for deploying OSGi based applications. Karaf is also a good platform for testing and debugging these applications. This article describes how to test and debug OSGi bundles and OSGi applications with karaf and eclipse.
The basic flow of development, is:
- Build the application with maven
- Start karaf as your own user in a way that makes it listen for remote debug connections
- Install the application from the karaf console
- Connect eclipse to karaf for a remote debug session
- Make karaf listen to updates to bundles with SNAPSHOT versions, and automatically load the updated bundles
- Make a change in eclipse
- Run a maven build of the project
- Observe that the change appears in karaf or in the debugger
For more detail, read on.
Preparations
Do the following:
- Install eclipse
- Open a web browser on https://www.eclipse.org/downloads/ and download the installer for your system
- Run the installer to the end, using defaults for everything
- Install apache maven
- On debian GNU/linux, just do
apt-get install maven
- On debian GNU/linux, just do
- Download and unpack the binary karaf distribution. In bash on GNU/linux (or in git bash on Windows), do:
mkdir -p ~/karaf cd ~/karaf/ wget http://apache.uib.no/karaf/4.1.4/apache-karaf-4.1.4.tar.gz tar --strip-components=1 -xf apache-karaf-4.1.4.tar.gz
Clone and build the sample application
- Clone and build the sample application
mkdir -p ~/workspaces/ws01 cd ~/workspaces/ws01/ git clone https://github.com/steinarb/hello-karaf-demo.git cd ~/workspaces/ws01/hello-karaf-demo/ mvn clean install
- Import the sample application into eclipse:
- Start eclipse
- Open the workspace at ~/workspaces/ws01
- Import the existing maven project hello-karaf-demo into the workspace (File->Import… then select Maven->Existing Maven Projects and click the wizard through to the end)
Install the application into karaf
- Open a command line window and start karaf with an argument that makes karaf listen for remote debug connections
cd ~/karaf/ bin/karaf debug
- From the karaf console prompt:
- Install the run-time requirements for the test application
feature:repo-add mvn:no.priv.bang.osgi.service.adapters/service-adapters-karaf/1.0.0/xml/features feature:install adapter-for-osgi-logservice feature:install pax-http-whiteboard
- Install the sample application with the following commands
bundle:install mvn:no.priv.bang.demos/hello-karaf-demo/1.0.0-SNAPSHOT bundle:start mvn:no.priv.bang.demos/hello-karaf-demo/1.0.0-SNAPSHOT
- Install the run-time requirements for the test application
- Open a web browser on the following URL http://localhost:8181/hello
Debug into the application running in karaf
- Set up a remote debug connection in karaf
- Open the menu Run->Debug Configurations…
- In the debug configurations dialog:
- Select “Remote Java Application”
- Click the “New launch configuration”
- In the Name field, write
Remote karaf debug
- In the Port field, write
5005
- Select the “Source” tab
- Click the button “Add…”
- In the “Add Source” dialog:
- Select “Java Project”
- Click the button “OK”
- In the “Project Selection” dialog
- Click the checkbox of “hello-karaf-demo”
- Click the button “OK”
- Click the button “Debug”
- Set a breakpoint in the code
- Open the HelloServlet.java file (press Ctrl-Shift-t to open the “Open Type” dialog, type HelloServlet and select the HelloServlet class)
- Go to line 60 (press Ctrl-l, then type 60, and press Enter), i.e. this line
response.setStatus(200);
- Press Ctrl-Shift-b to set a breakpoint on line 61
- Reload the web page in the web browser
- Observe that the debugger stops at the breakpoint
- Press F8 to make the code continue to run
Make a modification in the code, picked up by karaf
-
- In the karaf console, give the following command to make karaf listen in the local repository for new versions of bundles with SNAPSHOT version
bundle:watch *
- Modify the code in eclipse
- In the HelloServlet.java file, change
private static final String TITLE = "Hello world!"; private static final String PARAGRAPH = "This is sent via PAX Web Whiteboard Extender.";to
private static final String TITLE = "Hello karaf world!"; private static final String PARAGRAPH = "Powered by Apache Karaf."; - Save the HelloServlet.java file
- In the HelloServlet.java file, change
- Build the project with maven
- In eclipse, select the menu Run->Run Configurations…
- In the dialog Run Configurations:
- Reload the web page in the web browser and observe that the change now is present
- In the karaf console, give the following command to make karaf listen in the local repository for new versions of bundles with SNAPSHOT version
Installing with a karaf feature
In the installation example earlier in this article the runtime requirements of the sample application were first installed into karaf (pax-http-whiteboard and adapter-for-osgi-logservice).
It is possible to install this example application in a way that also pulls in the dependencies:
- The first thing to do, is to remove the existing installation in karaf:
- Stop karaf
logout
- Remove the “data” subdirectory
rm -rf data
- Start karaf
bin/karaf debug
- Stop karaf
- Removing the data directory removes all state in karaf, and karaf is back to a fresh installation, this can be verfied by:
- listing the bundles in the karaf console
bundle:list
- Verifying that http://localhost:8181/hello results in a 404 Not Found
- listing the bundles in the karaf console
- The first thing to do, is to add the feature repository for the hello world application. The feature repository is an XML file containing one or more “karaf features”. A karaf feature can be a list of bundles to load, and it can also contain references to other features. The feature file for the hello world application is attached to the maven bundle artifact and can be installed with the following command:
feature:repo-add mvn:no.priv.bang.demos/hello-karaf-demo/1.0.0-SNAPSHOT/xml/features
Note: This is the same karaf commando as the first command of the dependencies install. The pax-http-whiteboard feature is built-in to karaf and doesn’t require a feature repository install
- Now the feature for the hello world application can be installed
feature:install hello-karaf
- Verify that the feature install has pulled in dependencies
bundle:list
- Verify that the application is running on http://localhost:8181/hello
Some things to try on your own:
- Remove the data directory again and try installing the bundle without the dependencies and see what happens
- Start karaf watching for bundle modifications in the local maven repository
- List bundles on different levels with the bundle:list command with the threshold argument (hint: all karaf commands take the “–help” argument)
- Try launching the “mvn install” for the bundle using eclipse hotkeys after modifying the java file and observe that karaf loads the rebuilt module
Using above example, I tried start camel context using init method of servlet but it is gibving below error:-
org.apache.camel.RuntimeCamelException: java.lang.ClassNotFoundException: org.apache.camel.converter.stream.StreamCacheConverterLoader
at org.apache.camel.RuntimeCamelException.wrapRuntimeException(RuntimeCamelException.java:68)
at org.apache.camel.support.service.ServiceSupport.start(ServiceSupport.java:112)
at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:71)
at org.apache.camel.impl.engine.AbstractCamelContext.internalAddService(AbstractCamelContext.java:1407)
at org.apache.camel.impl.engine.AbstractCamelContext.doAddService(AbstractCamelContext.java:1357)
at org.apache.camel.impl.engine.AbstractCamelContext.doAddService(AbstractCamelContext.java:1352)
at org.apache.camel.impl.engine.AbstractCamelContext.doAddService(AbstractCamelContext.java:1348)
at org.apache.camel.impl.engine.AbstractCamelContext.setTypeConverter(AbstractCamelContext.java:1699)
at org.apache.camel.impl.engine.AbstractCamelContext.getTypeConverter(AbstractCamelContext.java:1691)
at org.apache.camel.impl.engine.AbstractCamelContext.doStartStandardServices(AbstractCamelContext.java:3306)
at org.apache.camel.impl.AbstractModelCamelContext.doStartStandardServices(AbstractModelCamelContext.java:283)
at org.apache.camel.impl.engine.AbstractCamelContext.forceLazyInitialization(AbstractCamelContext.java:3296)
at org.apache.camel.impl.engine.AbstractCamelContext.doStartCamel(AbstractCamelContext.java:2550)
at org.apache.camel.impl.engine.AbstractCamelContext.lambda$doStart$2(AbstractCamelContext.java:2439)
at org.apache.camel.impl.engine.AbstractCamelContext.doWithDefinedClassLoader(AbstractCamelContext.java:2456)
at org.apache.camel.impl.engine.AbstractCamelContext.doStart(AbstractCamelContext.java:2437)
at org.apache.camel.support.service.ServiceSupport.start(ServiceSupport.java:99)
at org.apache.camel.impl.engine.AbstractCamelContext.start(AbstractCamelContext.java:2346)
at co.hotwax.initializers.CamelService.init(CamelService.java:56)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
Hi, there isn’t anything in the https://github.com/steinarb/hello-karaf-demo that pulls in stuff from camel so that’s not surprising. 🙂
Here’s a karaf exampe that uses camel with OSGi blueprint (which is a different dependency injection method to SCR aka. DS (“Declarative Services”) that the hello-karaf example uses): https://github.com/apache/karaf/tree/master/examples/karaf-camel-example
Here’s some dated (4 year old) documentation that describes how to use camel with SCR/DS: https://cwiki.apache.org/confluence/display/CAMEL/Camel+and+SCR
(all maven references are probably dated, but the SCR annotations like e.g. @Component looks current)
Unfortunately I don’t use camel myself so that’s the best I can do. But it might be an idea to as the karaf-users list for tips: https://cwiki.apache.org/confluence/display/KARAF/Mailing+Lists
Hi!
I am trying to run your excellent tutorial but have run into a problem.
I followed the steps exactly but got an error when I ran this step:
bundle:start mvn:no.priv.bang.demos/hello-karaf-demo/1.0.0-SNAPSHOT
The error is:
Error executing command: Error executing command on bundles:
Error starting bundle 101: Unable to resolve no.priv.bang.debug-utils.hello-karaf-demo [101](R 101.0): missing requirement [no.priv.bang.debug-utils.hello-karaf-demo [101](R 101.0)] osgi.wiring.package; (&(osgi.wiring.package=no.priv.bang.osgi.service.adapters.logservice)(version>=1.1.0)(!(version>=2.0.0))) Unresolved requirements: [[no.priv.bang.debug-utils.hello-karaf-demo [101](R 101.0)] osgi.wiring.package; (&(osgi.wiring.package=no.priv.bang.osgi.service.adapters.logservice)(version>=1.1.0)(!(version>=2.0.0)))]
I checked to see if any of the previous steps have loaded a bundle that exports no.priv.bang.osgi.service.adapters.logservice, using this command:
karaf@root()> exports | grep no.priv.bang.osgi.service.adapters.logservice
no.priv.bang.osgi.service.adapters.logservice │ 1.0.0 │ 52 │ no.priv.bang.osgi.service.adapters.logservice
This shows there is indeed a bundle that is exporting the required package no.priv.bang.osgi.service.adapters.logservice.
However, the packaged exported is version 1.0.0, and the application requires version 1.1.0 or higher and lower than 2.0.0.
Bundles currently loaded include:
karaf@root()> list –no-format
START LEVEL 100 , List Threshold: 50
32 Active 80 4.3.9 Apache Karaf :: OSGi Services :: Event
52 Active 80 1.0.0 Adapter for OSGi log service
61 Active 80 4.21.0 Apache XBean :: OSGI Bundle Utilities
62 Active 80 4.21.0 Apache XBean :: Classpath Resource Finder
90 Active 80 9.4.0 org.objectweb.asm
91 Active 80 9.4.0 org.objectweb.asm.commons
92 Active 80 9.4.0 org.objectweb.asm.tree
93 Active 80 9.4.0 org.objectweb.asm.tree.analysis
94 Active 80 9.4.0 org.objectweb.asm.util
101 Installed 80 1.0.0.SNAPSHOT Pax Web Whiteboard extender hello world application
Bundle 52 exports:
karaf@root()> exports -b 52 –no-format
no.priv.bang.osgi.service.adapters.logservice 1.0.0 52 no.priv.bang.osgi.service.adapters.logservice
Thank you very much 🙂
Ann
Hi,
This blog post is pretty old. 5 years is a long time in this business. 🙂
I first tried downloading karaf 4.1.4, but it didn’t start on java17 (which is the only jre I currently have installed).
So I tried with karaf 4.4.3 and followed the instructions in the blog post and got the problems you’re seeing.
So I tried the instructions in the README:
feature:repo-add mvn:no.priv.bang.demos/hello-karaf-demo/LATEST/xml/features
feature:install hello-karaf
and… got an error for pax-http-whiteboard missing.
The built-in pax-http-whiteboard feature was renamed to just “http-whiteboard” a while back, but it looks like I didn’t update the hello-karaf-demo.
According to git I updated some stuff 3 months ago, but I probably never tried running it.
I have now updated all maven dependencies while I was at it, and done the necessary changes for OSGi 8 SCR (which is what karaf 4.4.x uses) and the app loads from the feature
So if you do
git pullmvn clean install
and then in the karaf console do
feature:repo-add mvn:no.priv.bang.demos/hello-karaf-demo/LATEST/xml/featuresfeature:install hello-karaf
then the app should be up and running at http://localhost:8181/hello
Note that I have since made more comprehensive demos than hello-karaf-demo, the last, and most complete, being https://github.com/steinarb/sampleapp (it has liquibase database setup and authentication and authorization by apache shiro)