I implemented an OSGi-bundle which gets some other services injected according to its service.xml. It turns out, that my bundle does get activated if the activation policy is set to lazy. The other services are injected correctly.
The main problem is, that the bundle is started and stopped several times depending on the number of other services injected. If I reduce the number of injected services to only one the bundle is started only once. By injecting 5 other services it starts and stops 3 times in which the last start is not stopped so the service which starts a TCP server is working fine then. Even though it works fine, this behaviour is strange and completely unintended.
I am not sure how to avoid that as I do not have any clue how this happens.
LOG:
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 22735430 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 28219381
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.B.SimServiceComponent - Stopping SimService now . . . 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - SimService stopped.
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 28883317 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Stopping SimService now . . . 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - SimService stopped.
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 31287346 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 33352835
service.xml:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" immediate="true" name="SimService">
<implementation class="SimServiceComponent"></implementation>
<service>
<provide interface="ServiceComponent"></provide>
</service>
<reference bind="setA" cardinality="1..1" interface="A" name="A" policy="static"/>
<reference bind="setB" cardinality="1..1" interface="B" name="B" policy="static"/>
<reference bind="setC" cardinality="1..1" interface="C" name="C" policy="static"/>
<reference bind="setD" cardinality="1..1" interface="D" name="D" policy="static"/>
<reference bind="setE" cardinality="1..1" interface="E" name="E" policy="static"/>
</scr:component>
Activate method and sample of service setters:
public void setA(final A a) {
LOG.info("Setting a {} for instance {} ", a.hashCode(), hashCode());
_a = a;
}
public void setB(final B b) {
LOG.info("Setting b {} for instance {} ", b.hashCode(), hashCode());
_b = b;
}
public void activate(BundleContext bundleContext) throws Exception {
LOG.info("Starting SimService now . . . {}", hashCode());
}
Thanks for your help :-)
EDIT:
The service inside this bundle is not consumed by any other bundle/service, so there are no cyclic dependencies.
Adding the hash code identities to your log messages was a smart move! It shows that although services A
, B
, D
and E
are constant, the identity of service C
changes each time.
This implies that the original C
service has unregistered from the service registry for some reason. Because your SimServiceComponent
component has a mandatory 1..1
reference to service C
, it is forced to deactivate when C
goes away. Then service C
comes back (more accurately, a new C
service is registered) which allows your component to be reactivated.
So you need to look into why the C
service is cycling.