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