Karaf: Using features
anton-johansson opened this issue · comments
I am planning on building a docker image of my application which runs on Karaf, and your Karaf docker image looks perfect. But I would want to install a feature (from my custom features.xml
file) instead of using hot-deployment. How would you recommend I do that? I see two alternatives:
- Write my own
org.apache.karaf.features.cfg
file and replace the built-in one - Send commands to Karaf somehow,
feature:repo-add mvn:xx/yy/zz/xml/features
andfeature:install abc
.
The features.xml
file is expected to exist in the local Maven repository at build-time.
Dear,
Docker best practices is to use immutable deployment, meaning you can't modify your image once it's build.
So it doesn't fit well with the dynamic nature of Karaf which by definition is designed to mutate its state once it is running.
- If you create your own org.apache.karaf.feature.cfg and if your don't have all your dependencies included in your image, it will download all your dependencies at its first start. I've already seen that my container fails to start from time to time due to an download error or something like that. So this solution is to avoid.
- The second option is better because you will download every dependencies at the image build time but I've met some issues here too because once the feature is installed, it stops the karaf directly without waiting that all bundles are started and sometimes you might be in an inconsistent state. The good new is that once your image is built correctly, it will work well for each container.
- A third option, which is my preferred one, is to build your custom karaf instance with the karaf maven bundle plugin and then add it on top of your favourite java image.
I didn't publish it as official karaf image because it's custom and depends on the needs. My karaf images can be used easily for development where you can have access to the container and install what you want but in production you must be sure that your image is built correctly and will run correct container instances.
Hope I'm clear, if you need help for that, I might publish an example. You can also check the one from fabric8's team
What you say makes a lot of sense, thanks. Yeah, I understand that the image should be complete at build time, and it makes sense that using a custom org.apache.karaf.features.cfg
file wouldn't allow that.
Side note, just curious: how about deploying docker images containing databases? Such as a mongodb server? I guess that would still count as immutable, even though data grows and changes in there?
About the second option, I might try that and see if I bump into the same issues as you.
Third option seems very good, yes. You mean packaging my application as a KAR? I haven't worked very much with KAR's yet, so I'm gonna have to read up a little on that first. Thanks for the advice!
For database, you will run a MongoDB container with a volume mounted in it that will contain the data. Volume are kind of special container in docker which doesn't run any process.
For the third option, I really build a complete karaf (not simply a KAR). The KAR should work (build it and drop it to deploy) but I when I tried I've also met issues :-(
Ah, of course. That makes sense.
Allright. I'm reading up on the karaf-maven-plugin
as we speak. I guess I can build a complete Karaf using the karaf-assembly
packaging instead of the kar
packaging. Just gonna figure it out. :)
Hmm, I can't quite figure it out. I have a POM like this:
https://gist.github.com/anton-johansson/6fa769c031bb99c8420d917330043af0
And it assembles a clean Karaf. But of course, I want to add my artifacts to the assembled Karaf. So I go ahead and add my features as a dependency:
<dependency>
<groupId>com.anton-johansson</groupId>
<artifactId>assembly-test-features</artifactId>
<version>${project.version}</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
Then I get assembly errors, like so:
Unable to build assembly: Unable to resolve root: missing requirement [root] ...
My features are built correct and work if I run them in a standalone (regular) Karaf. Not sure why it won't resolve dependencies and stuff. Does karaf-maven-plugin
handle dependencies differently or something? My feature installs another feature: CXF.
You have any idea?
Hmm, turns out that my bundles contain the following MANIFEST-header:
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
This is good, since I use Java 8 code, it's nice to tell the container that I require Java 8. However, that's when karaf-assembly
gives me the error that ends with: missing requirement [assembly-test-commons/1.0.0.SNAPSHOT] osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=1.8))"
. Do you know why it doesn't work with a Java 8 requirement?
If I remove the Require-Capability
header (through the instruction <_noee>true</_noee>
in maven-bundle-plugin
), my assembly is generated perfectly, and it runs without any problem.
Mmmmhhh sorry, I don't see where can be the error here, but it works with java 8. I did a similar thing for one of my client last year, unfortunately, I don't have the project anymore.
If you can share your project on github, I could take a look if you want.