Karaf is an OSGi container rather than a WAR container. Hence it is not as easy to deploy your WAR into Karaf as opposed to, say, Tomcat. You basically have three options:
- Split your WAR into separate jars, add OSGi descriptors to all of those so that Karaf recognizes them as OSGi bundles, then plug your servlets into Karaf's pax-web something. That's a lot of work.
- Repackage your WAR as JAR with JARs, add OSGi descriptor so that Karaf recognizes that as a big bundle, then plug your servlets into Karaf's Pax-Web. That's still a lot of work.
- Use WAR Deployer and just copy your WAR to the
deploy/folder. Ta-daa! This is the easiest way of deploying WAR to Karaf, the one that doesn't require you to add OSGi manifests to your WAR and/or tackle the XML bundle configurations. Let's go.
Using Karaf WAR Deployer
First, download Karaf, the Karaf Runtime is enough. Unpack it, go into the
bin/ folder and run it:
./karaf. Karaf will start and will present you with a console. Great. First lesson is inspired by vim: we'll learn how to quit. Luckily that's easy, just press
We'll use the Karaf WAR deployer which is able to take a WAR file, add all necessary OSGi descriptors automatically and deploy the WAR file on an internal Jetty server (or whatever is configured to be used by the Pax-Web OSGi Http Service). In the Karaf console, type in:
This will install the
http feature (which is a basic support for serving http in OSGi),
http-whiteboard (which allows for mapping servlets to context roots I guess) and
war which is the WAR Deployer itself. You can verify that everything is installed, by listing features:
WAR Deployer is old-fashioned and requires
web.xml to be present in the WAR file in order to be recognized and deployed properly by Karaf. Just add the following dummy
web.xml to your WAR project's
That is enough - Jetty will properly autodiscover all of your servlets and other annotated stuff. Now build your WAR file. You can use any Vaadin-based webapp; for the purpose of this text we're going to experiment on the karibu-helloworld-application Vaadin 8 webapp. Just don't forget to add the
web.xml, then run
./gradlew and find the WAR file in
Note: Vaadin 10 apps will crash with NPE for some reason, please feel free to report a bug to the Vaadin folk.
Copy the WAR file into Karaf's
deploy/ folder. The WAR file should be picked up automatically and launched. You can follow the log of your app in Karaf by using the
log:tail Karaf command - consult the log for any exceptions or other deployment failures. You can also use the
web:list command to check that your app is up and running, for example:
Now you can go and see your app running on http://localhost:8181/karibu-helloworld-application. Enjoy.
@Push via WebSockets will not work with Vaadin 7.7.x and Karaf 4.1.6 and will fall back to longpolling, because the bundled Jetty is newer than Vaadin expects and Vaadin will fail with
java.lang.ClassNotFoundException: org.eclipse.jetty.websocket.server.WebSocketServerFactory. You need to force Vaadin to use JSR356 in Atmosphere:
Now we'll get
java.lang.RuntimeException: Cannot load platform configurator. because OSGi doesn't support standard stuff like ServiceLoader out-of-the-box. On Stackoverflow there is a solution, but luckily a proper artifact is already provided by the servicemix people. First remove all of your WAR files from the
deploy/ folder. Stop Karaf and run it with
./karaf clean. Then, in your karaf console:
And now try to redeploy your WAR file. If you don't to start from a clean state, you can get
java.lang.ClassCastException: org.eclipse.jetty.websocket.jsr356.server.ServerContainer cannot be cast to javax.websocket.server.ServerContainer (that's your app loaded by a classloader which references old javax-websocket-api classloader); if you fail to remove the old
javax.websocket-api you can still get the
Cannot load platform configurator error.
Karaf, employing OSGi and class loaders, may suprise you with lots of nasty exceptions. Be careful to start with a clean state, and repeat the steps if necessary.