I am new to Karaf and Camel and I'm trying to deploy custom camel routes (java) and I'm facing a lot of problems at the time of deploying the camel bundle (.jar) in the hot deploy directory.
What I got so far:
Apache Karaf 4.3.1 running in docker container
Bundle .jar with the java defined route
My idea is to have a /deploy directory mapped to the karaf container so any .jar that's added to that directory is deployed (or maybe build a new image for karaf).
When I tried to add my current bundle to the directory I got the following error message:
20:19:32.490 INFO [fileinstall-/opt/karaf/deploy] Installing bundle org.apache.karaf.examples.karaf-camel-example-java / 4.3.1
20:19:32.535 WARN [fileinstall-/opt/karaf/deploy] Error while starting bundle: file:/opt/karaf/deploy/karaf-camel-example-java-4.3.1.jar
org.osgi.framework.BundleException: Unable to resolve org.apache.karaf.examples.karaf-camel-example-java [111](R 111.0): missing requirement [org.apache.karaf.examples.karaf-camel-example-java [111](R 111.0)] osgi.wiring.package; (&(osgi.wiring.package=org.apache.camel)(version>=3.6.0)(!(version>=4.0.0))) Unresolved requirements: [[org.apache.karaf.examples.karaf-camel-example-java [111](R 111.0)] osgi.wiring.package; (&(osgi.wiring.package=org.apache.camel)(version>=3.6.0)(!(version>=4.0.0)))]
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4368) ~[?:?]
at org.apache.felix.framework.Felix.startBundle(Felix.java:2281) ~[?:?]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998) ~[?:?]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [!/:3.6.8]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [!/:3.6.8]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:520) [!/:3.6.8]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [!/:3.6.8]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [!/:3.6.8]
I think this can be solve with a maven bundle "wrap" but I'm not sure if this is correct, and if so, how should I wrap the bundle?
Thank you for reading :D
A bit late but hope this helps someone as I've fiddled with this setup quite a bit for the past year while exploring OSGi, Karaf, Camel and Docker.
If you want to do local development with karaf you can actually map your maven repository to the container which can make installing bundles and features quite a bit easier.
Example Docker compose for Karaf
Here's a docker-compose for karaf 4.2.11 but you can probably change it to 4.3.1 without any problems. (add :z on volumes if using SELinux)
version: "2.4"
services:
karaf-runtime:
container_name: karaf
image: apache/karaf:4.2.11
ports:
- 8101:8101
- 8181:8181
- 1098:1098
volumes:
- ./karaf/etc:/opt/apache-karaf/etc
- ./karaf/deploy:/opt/apache-karaf/deploy
- karaf-data:/opt/apache-karaf/data
- ~/.m2:/root/.m2
- karaf-history:/root/.karaf
command: [ karaf, server ]
volumes:
karaf-data:
karaf-history:
Just save it to a empty folder somewhere as docker-compose.yml. Create folder named karaf to the folder and then fetch the default configurations from karaf using couple docker commands:
# Start detached karaf container with name karaf
docker run --name karaf -d apache/karaf:4.2.11
# copy files from container to host-system
docker cp karaf:opt/apache-karaf/etc ./karaf/
# stop the container
docker stop karaf
Setting karafs etc folder as shared volume makes it easy to tweak and share the configurations through version control for other developers.
To start Apache karaf with docker compose you can use following commands:
# Start
docker compose up -d
docker-compose up -d
# Stop
docker compose down
docker-compose down
# note: docker compose = newer version of docker-compose command
Creating bundles
Easy way to create bundles is to use one of the official archetypes karaf-bundle-archetype or karaf-blueprint-archetype when creating the project.
For projects using Apache Camel it is generally easier to use karaf-blueprint-archetype. With it you configure the CamelContext in the xml blueprint file found in projects resources/OSGI-INF/blueprint/ folder.
Example:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="ExampleRoute" class="com.example.ExampleRouteBuilder" />
<camelContext id="ExampleContext" xmlns="http://camel.apache.org/schema/blueprint">
<routeBuilder ref="ExampleRoute" />
</camelContext>
</blueprint>
With ~/.m2:/root/.m2 shared volume you can just package the project using mvn clean install to your local maven repository which you can then use in karaf to install the bundle using bundle:install mvn:groupId/artifactId/version
If you want to use deploy folder you can copy artifacts to container using docker cp ./target/exampleBundle.jar karaf:/opt/apache-karaf/deploy
Adding camel feature to karaf
As for camel you can follow the official guide on how to add camel feature repository and the features you need.
But the steps are basically:
# Add camel feature repo
feature:repo-add camel <version>
# Install camel feature
feature:install camel
# List available camel features for install
feature:list | grep camel
# Install camel features you need
feature:install <feature-name>
Missing requirements
When installing bundles often encounter missing requirement exception that tells you that package that the bundle depends on is missing from karaf which means you'll have to install bundle or feature that exports the said package.
These messages are usually best read starting from the end:
(osgi.wiring.package=org.apache.camel)(version>=3.6.0)(!(version>=4.0.0)
The above tells you that karaf installation doesn't have camel installed. OSGi bundles expect OSGi framework/runtime to satisfy their dependencies which is quite a bit different from say standalone SpringBoot projects.
Shared volumes and new files
When it comes to sharing config files or karaf deploy folder it's good to know that Docker has some issues related to new files in shared volumes. If new file is added/created using host-systems file-system there's chance that karaf will not detect these files or changes made to them.
It's generally better to use docker cp path/to/file/on/host karaf:/path/to/folder/on/container to deploy new files to container even if its shared volume.
otherwise you might have to shell in to the container and make copy of the file in question and
Related
I have a maven project structured:
/root
/CommonProject
/executable1
/executable2
/subroot
/subrootCommon
/...
So far I am trying to just deploy executable1.
I wanted to the project to use Java 19, I am fine with Java 17 if it's easier.
When I activate cloud shell, I am able to:
Change $JAVA_HOME to jdk 17
clone project
maven package it
run it in cloud shell.
However my project has no mapping for "/", just specific endpoints like "/test/hello" and I do not see anything in WebPreview on port 8080.
I have tried different ways to deploy, I am not familiar enough with Docker, so I tried CloudRun with Cloud Build with trigger from Source.
Here lies my current problem - every build has failed so far. It is using jdk 11 which is a problem (or at least one of them).
I have tried also adding cloudbuild.yaml or local Dockerfile just to deploy jar built manually, but I am still failing.
+FROM openjdk:17
+COPY root/target/executable1-1.0-SNAPSHOT-jar-with-dependencies.jar /home/user/var/run/executable1.jar
+CMD ["java", "-jar", "/home/user/var/run/executable1.jar"]
I have done the same steps to deploy, which were shown in how-to-guides or available online labs, so I think the issue is with the fact that maybe buildpacks do not process correctly projects with dependencies?
executable1 and executable2 depend on CommonProject. Do I need to split my big maven project into separate projects, to build each of them individually?
I have tried Dockerfile, cloudbuild.yaml, something like project.toml.
I would like to deploy for now just 1 project, at one point in the future all executable projects from this maven.
I am developing an OSGI-based application, which deploys to Karaf container. Karaf has an auto-deployment feature, whereby copying a bundle to its karaf/deploy directory should automatically deploy that bundle into the container. More often than not, however, I am getting errors similar to the one below when I copy bundles into the deploy directory:
org.osgi.framework.BundleException: Bundle symbolic name and version are not unique: legacy-services-impl:8.0.0.ALPHA-SPRINT9-SNAPSHOT
at org.apache.felix.framework.BundleImpl.createRevision(BundleImpl.java:1225)
at org.apache.felix.framework.BundleImpl.<init>(BundleImpl.java:95)
at org.apache.felix.framework.Felix.installBundle(Felix.java:2979)
at org.apache.felix.framework.BundleContextImpl.installBundle(BundleContextImpl.java:165)
at org.apache.felix.fileinstall.internal.DirectoryWatcher.installOrUpdateBundle(DirectoryWatcher.java:1030)[6:org.apache.felix.fileinstall:3.3.11.fuse-71-047]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.install(DirectoryWatcher.java:944)[6:org.apache.felix.fileinstall:3.3.11.fuse-71-047]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.install(DirectoryWatcher.java:857)[6:org.apache.felix.fileinstall:3.3.11.fuse-71-047]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:483)[6:org.apache.felix.fileinstall:3.3.11.fuse-71-047]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:291)[6:org.apache.felix.fileinstall:3.3.11.fuse-71-047]
Instead of redeploying an already deployed bundle, the container tells me that I am trying to deploy a duplicate bundle.
The Karaf indeed has that bundle deployed, but why wouldn't it redeploy the bundle? What is causing this behavior? How to avoid such errors on auto-deploy?
Thank you,
Michael
I suspect that your bundle does not stop correctly. That may be the reason why karaf thinks it is still there. Do you have some code in your activator that is executed when stopping? Perhaps you are also running some threads. You should make sure the stop method of your activator works and cleanly closes all resources and stops all threads of your bundle.
I have built an application based on play framework 2.0.3. I have placed some jars in lib folder (unmanaged dependencies) which are used in my application like suggested in How to put a JAR file in a Play 2 project and use it?
All is fine when I run it from my local machine with play run
But when this application is deployed to Heroku, these jars are not picked up. I get compilation errors where these jars are used.
I even tried adding dependencies.yml with below content
require:
- play 2.0.3
- provided -> myjar 1.0
repositories:
- provided:
type: local
artifact: "${application.path}/lib/[module]-[revision].jar"
contains:
- provided -> *
But still it didn't work.
My Start script (Procfile) is :
web: target/start -Dhttp.port=${PORT} ${JAVA_OPTS} -DapplyEvolutions.default=true -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=${DATABASE_URL}
Can somebody throw some light on this problem ?
Since heroku uses git, make sure that you lib folder and all contained jars are properly managed by git, ie that they are not in your .gitignore file.
I want to start Camel and ActiveMQ during boot when I start karaf, What i've found is the etc/org.apache.karaf.features.cfg which lists features that should be started during boot.
featuresBoot=config,ssh,management,camel,activemq,camel-jms,activemq-spring,activemq-camel
This works fine for all but 'activemq-camel' (fair enough, since it's not a feature).
To get the apache-camel bundle installed i've to run run the command:
karaf#...>osgi:install -s mvn:org.apache.activemq/activemq-camel/5.5.0
It works, but I'd rather just get it running at boot time.
Can I somehow get the activemq-camel bundle to be installed at boot time without creating a custom feature for it?
Apache ServiceMix has this feature already defined. To use it add mvn:org.apache.servicemix/apache-servicemix/4.4.1/xml/features to the featuresRepositories property in etc/org.apache.karaf.features.cfg and then camel-activemq to the featuresBoot property.
Cheers,
Jon
I am searching for a way to generate a run able equinox configuration of deployed OSGI bundles.
A build server deploys our OSGI bundles via maven and tycho-plugin and placed them in the m2 directory.
Now, the next step is to collect the bundles from the deployment directory and put them together in a equinox configuration and start up the container.
Collect the bundles and configure the equinox container manually is not the way I prefer so now I looking for a way to do this automatically via script.
There are solutions like ANT script?
Hoping for Help
Build a "product" (i.e. a fully self-contained OSGi runtime).
See the tycho docs in general [1] and esp. exercise 5 of the tycho tutorial [2] with solution [3]
[1] http://eclipse.org/tycho/documentation.php
[2] http://eclipsecon.org/sessions/building-eclipse-plugins-and-rcp-applications-tycho
[3] https://github.com/jsievers/tycho-demo/tree/master/exercises/Exercise_06_Solution
One thing you could do is generate an config.ini file which you can put in your configuration/ directory. The osgi.bundles entry in there allows you to specify what bundles to install and start, e.g.:
config.ini content:
osgi.bundles=org.eclipse.osgi.services#start, ../mydirectory/mybundle.jar#start
You may need to specify the configuration directory when launching equinox to ensure the config.ini is picked up, e.g.
java -jar plugins/org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar -configuration configuration
You can use https://github.com/sarod/equinox-config-builder to easily generate a config.ini from a plugins directory.