I just stumbled over a phenomenon in my code which comes down to this:
I have an OSGi Declarative Service providing two service interfaces configured as follows:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="dispose" enabled="true" name="redacted.redactedstore">
<implementation class="redacted.RedactedStore"/>
<service>
<provide interface="redacted.IRedactedStore"/>
<provide interface="redacted.IRedactedStoreControl"/>
</service>
</scr:component>
In my code, I have two different threads which both open a ServiceTracker
to get the service instance, but via different interfaces:
tracker = new ServiceTracker<>(getBundle().getBundleContext(), <serviceClass>.class, null);
tracker.open();
tracker.waitForService(1000l);
So one thread uses IRedactedStore
as service class and the other uses IRedactedStoreControl
as service interface.
So what seems to happen is that when both threads run in parallel at the right time, the Equinox SCR will instantiate not one (as I would expect) but two instances of the component implementation class.
Is this behavior correct? Or is this a bug in the Equinox implementation of OSGi?
If the behavior is correct, can I do something in my code to prevent that by configuring the service another way? (of course I could restructure the service so it only provides one interface, or I could synchronize the service trackers...)
For non prototype scope component I would expect that it is created only once. See declarative services spec.
If this issue only happens when the service trackers run in parallel then I suspect it might be an concurrency issue in equinox scr.