I'm experiencing what I believe it's an strange behaviour from Osgi services and their tracking.
I've got two bundles: Provider
and Client
. Provider offers the "comm service" which Client receives and uses.
At the beginning, Client retrieved the service via the OSGi TrackerService thanks to this method on the ClientActivator
class:
private CommService retrieveCommService(BundleContext bc)
throws InterruptedException {
//create the tracker
ServiceTracker tracker = new ServiceTracker(bc, CommService.class.
getName(), null);
tracker.open();
//timeout of 5 seconds to find the service
CommService service = (CommService) tracker.waitForService(5000);
tracker.close();
return service;
}
This way, the tracker found the service when the activator of the Client
bundle was executed.
If the ServiceTracker works properly, this is what I see when I type services on the OSGi console:
{some.project.folder.imaComms.CommService}={service.id=46}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
Anyway, after reading several documentation about OSGi services, I decided to use DS instead of ServiceTrackers.
So, I created the components (provider and client xml files) and implemented the bind and unbind methods:
public void setComms(CommService comm){
this.comm = comm;
System.out.println("got comms!");
}
public void unsetComms(CommService comm){
this.comm=null;
System.out.println("lost comms..");
}
And, this time, this is what I see when I type services on the Console:
{some.project.folder.imaComms.CommService}={component.name=
MA_Comm_Provider, component.id=18, service.id=47}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
So, whenever I stopped the Provider
bundle, the message lost comms... appeared on console. When I started it again, got comms! was the message.
Everything perfect so far. But I wanted to make a last test. I implemented the bind and unbind methods, the component definition, but I also let the ServiceTracker find the service on the ClientActivator.
The result is somehow strange.
When I start the OSGi framework, got comms! appears on console, as if the DS bind method was working and offering the service to my Client
. But if I type services, this is what I got:
{some.project.folder.imaComms.CommService}={service.id=46}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
{some.project.folder.imaComms.CommService}={component.name=
MA_Comm_Provider, component.id=18, service.id=47}
Registered by bundle: MA_Provider [2062]
No Bundles using this service.
The Client is using the service via ServiceTracker. If I stop the ProviderService, I got this message from the unbind method: *lost comms...*
What happens if I start the bundle again? Yeah, "got comms!" appears on console...but then again, if I take a look at services, the service id 47 (DS service) is not being used by anyone. What? O_o
Any clue of what's going on? Thanks in advance!
Also, forgot to mention: Whenever I restart the Provider
bundle, Osgi takes about 2-3 minutes starting the bundle, and it completely stops any other bundles' work.
UPDATE 28/03/14
XML files for provider and client DS
Provider
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="MA_Comms_Provider">
<implementation class="some.project.folder.maComms.CommServiceImpl"/>
<service>
<provide interface="some.project.folder.imaComms.CommService"/>
</service>
</scr:component>
Client
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="MA_Comms_consumer">
<implementation class="some.project.folder.maClient.MyClientImpl"/>
<reference bind="setComms" cardinality="1..1" interface="some.project.folder.imaComms.CommService" name="CommService" policy="static" unbind="unsetComms"/>
</scr:component>
Manifest files for Provider and Client
Provider
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MA_Provider
Bundle-SymbolicName: MA_Provider
Bundle-Version: 1.0.0
Bundle-ClassPath: src/,
.
Bundle-Activator: myActivator
Export-Package: ...
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: ...,
org.osgi.framework;version="1.5.0",
org.osgi.util.tracker;version="1.4.2"
Service-Component: OSGI-INF/CommsProvider.xml
Client
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MaClient
Bundle-SymbolicName: MA_Client
Bundle-Version: 1.0.0
Bundle-ClassPath: src/,
.
Bundle-Activator: ...
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: ...,
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.2"
Export-Package: es.techabout.meetabout.macomms
Service-Component: OSGI-INF/CommsConsumer.xml, ...
It should be noted that I omitted the real names of folders, classes and services, so even if my text has any error regarding names of classes, folders ..., I assure you that the real project is build with no errors whatsoever.