I am using Apache Karaf 4.1.1 and Karaf Cellar. I have written two bundles. The first bundle provides a service of type ITrackerManager. The second bundle has a component that references ITrackerManager. My end goal is to witness the component in the second bundle successfully get a reference to the ITrackerManager service in the first bundle which is running on a different node. This is all part of my exploration of distributed OSGi.
What is actually happening when I install that second bundle is that it gets installed but fails to activate due to missing the service reference. I must be conducting my test incorrectly. Any ideas on how I would go about demonstrating my end goal; component in bundle on Node B successfully uses service on Node A?
Here is how I have run my test so far.
Node A
karaf@root()> cluster:node-list
| Id | Alias | Host Name | Port
--+-------------------+-------+--------------+-----
x | 159.4.251.58:5701 | | 159.4.251.58 | 5701
| 159.4.251.58:5702 | | 159.4.251.58 | 5702
Node B
karaf@root()> cluster:node-list
| Id | Alias | Host Name | Port
--+-------------------+-------+--------------+-----
| 159.4.251.58:5701 | | 159.4.251.58 | 5701
x | 159.4.251.58:5702 | | 159.4.251.58 | 5702
So far so good. I am running two karaf instances on my computer. Both instances see each other. Now I want to install that first bundle onto Node A ONLY. To accomplish that, I install the bundle into the cluster, then specifically remove it from Node B.
Node A
karaf@root()> cluster:bundle-install -s default mvn:myCompany/dosgi-example-part1/1.0-SNAPSHOT
karaf@root()> cluster:bundle-list default
Bundles in cluster group default
ID | State | Lvl | Located | Blocked | Version | Name
---+----------+-----+---------------+---------+----------------+--------------------------------------------------------------
0 | Active | | cluster/local | | 5.6.2 | System Bundle
...
67 | Active | | cluster/local | | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1
karaf@root()> cluster:service-list
Service Class | Provider Node
--------------------------+------------------
myCompany.ITrackerManager | 159.4.251.58:5701
| 159.4.251.58:5702
Still looking good. My bundle is in the cluster, is local on Node A (and Node B at this point), and the service is recognized by the cluster and is available on both Node A and Node B. Now to remove the bundle from Node B.
Node B
karaf@root()> cluster:bundle-list default
Bundles in cluster group default
ID | State | Lvl | Located | Blocked | Version | Name
---+----------+-----+---------------+---------+----------------+-------------------------------------------------------------
67 | Active | | cluster/local | | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1
karaf@root()> bundle:list
START LEVEL 100 , List Threshold: 50
ID | State | Lvl | Version | Name
---+--------+-----+----------------+-----------------------------------------------
75 | Active | 80 | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1
karaf@root()> bundle:uninstall 75
karaf@root()> cluster:bundle-list default
Bundles in cluster group default
ID | State | Lvl | Located | Blocked | Version | Name
---+----------+-----+---------------+---------+----------------+--------------------------------------------------------------
67 | Active | | cluster | | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 1
karaf@root()> cluster:service-list
Service Class | Provider Node
--------------------------+------------------
myCompany.ITrackerManager | 159.4.251.58:5701
Excellent. The first bundle has been removed from Node B but still shows up as being in the cluster. Both nodes agree that my service is only available on Node A now (since the bundle was removed from Node B). Now I will load my second bundle on Node B only. This is where I run into problems. I don't load the second bundle using the cluster:bundle-install command because I don't want it ending up on Node A. So instead I install my second bundle using the normal bundle:install command. This results in an error about an unsatisfied reference.
Node B
karaf@root()> bundle:install -s mvn:otherCompany/dosgi-example-part2/1.0-SNAPSHOT
Bundle ID: 76
Error executing command: Error installing bundles:
Unable to start bundle mvn:otherCompany/dosgi-example-part2/1.0-SNAPSHOT: org.osgi.framework.BundleException: Unable to resolve otherCompany.dosgi-example-part2 [76](R 76.0): missing requirement [otherCompany.dosgi-example-part2 [76](R 76.0)] osgi.wiring.package; (&(osgi.wiring.package=myCompany)(version>=1.0.0)(!(version>=2.0.0))) Unresolved requirements: [[otherCompany.dosgi-example-part2 [76](R 76.0)] osgi.wiring.package; (&(osgi.wiring.package=myCompany)(version>=1.0.0)(!(version>=2.0.0)))]
karaf@root()> bundle:list
START LEVEL 100 , List Threshold: 50
ID | State | Lvl | Version | Name
---+-----------+-----+----------------+-----------------------------------------------------------------------------------------------------
76 | Installed | 80 | 1.0.0.SNAPSHOT | Distributed OSGi Example Part 2
So there it is. I install the second bundle on NodeB only, expecting that it is able to successfully use the required service which resides on Node A only. Unfortunately that does not happen. Instead I get error message stating there are unresolved requirements. It seems to behave as if DOSGI is not available. If I install both bundles on the same node, the second bundle activates without any errors. Any insights you may have would be appreciated.