You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Kris Pruden <kp...@gmail.com> on 2009/12/16 18:37:07 UTC

SCR interaction with ServiceTracker

Hi,

I'm puzzling through some strange behaviour in my application related  
to what appears to be a race and/or some weird interaction between  
services registered via SCR and bundles trying to monitor these  
services via the ServiceTracker API.

I don't have any good theories at the moment, so I was hoping if I  
described what I'm seeing it might job somebody's memory...

Here's my situation.  I have an application made up of about a half- 
dozen or so bundles, most (but not all) of which register their  
services using DS/SCR.  I'm using pax:exam to run automated functional  
tests for this application.  Unfortunately, my tests are not reliable  
- they fail intermittently.  When there's a failure, it's always  
because of an NPE on one of the SCR-injected @Reference attributes of  
a service/component.  It's hard to tell for sure, but what looks like  
is happening is this:
1. The SCR starts and registers a component/service
2. The functional test, which was waiting for that service to become  
available, gets a reference to the service
3. The SCR stops the service, then immediately starts and registers a  
new instance of the service

Unfortunately, at this point the test bundle now has a reference to  
the "stopped" instance of the service, which has had all of its  
@Reference fields set to null (hence the NPE).

What I can't figure out is why this is happening.

Anyone have any suggestions about where I should look next, or any  
known SCR gotchas that I might be running into?

Thanks,

Kris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: SCR interaction with ServiceTracker

Posted by Kris Pruden <kp...@gmail.com>.
On Dec 16, 2009, at 4:09 PM, Felix Meschberger wrote:

> Hi,
>
> Thanks for the update.
>
> I have to admit, that I cannot tell what's going on.

Yeah, it's very strange.

I've uncovered some more as I continue to investigate.  I've  
discovered that the start order of the bundles, particularly where SCR  
itself is started in relation to other bundles, affects the behaviour  
or the SCR.  I had another bundle I was testing with pax:exam that was  
behaving very strangely.  What I found was that my service component  
was being instantiated and registered by the SCR (i.e.  
context.getServiceReference returned non-null), but that component's  
activate method was not being invoked.

I confirmed this with a debugger (set a breakpoint on the activate  
method, which was never hit).

This led me to a question: what is the order in which the SCR performs  
the various lifecycle steps.  I had assumed it is this:
1. instantiate the component
2. bind references
3. run activator
4. register service

However, the above behaviour suggests that maybe it registers the  
service before calling the activator.

Now here's the weird part.  If I changed where in the list of bundles  
to be deployed by pax from somewhere in the middle to the end, it  
started working.

Is it possible the SCR has a synchronization whole where in certain  
circumstances it's possible for the SCR bundle to somehow "miss" some  
bundle or service events that happened while the SCR bundle itself was  
starting?

Perhaps to support this theory, I have observed, when running a  
manually configured, standalone felix instance, the SCR can sometimes  
fail to activate all components when the framework is initially  
started and allowed to start all the configured bundles willy-nilly.   
In this case, the SCR shows some of the dependencies as unsatisfied,  
however simply stopping and starting the bundle containing the  
component fixes it...

> From the POV of SCR it doesn't matter whether a service used to  
> satisfy
> a reference is registered through a regular Bundle Activator or  
> through
> SCR -- in fact SCR doesn't even know.

That's what I thought too :)

> Now, I think I have added fairly extensive logging information in SCR
> 1.2.0 (or at least I have done in the currently voted on 1.4.0 release
> candidate) -- logging mostly done at DEBUG level. This logging should
> indicate why SCR is taking down a component (and reactivating it).
>
> Generally a component is reactivated if a statically bound reference  
> has
> to be replaced (because the bound reference is unregistered).

Hmm, that is interesting.  If I change the binding to dynamic, that  
means the SCR will rebind the reference field on the fly any time the  
underlying service changes, is that right?  I'm not sure if that is  
the crux of my problem, but in most cases I think this is what I want  
anyway...

> Also SCR 1.2.0 reactivates a component if service registration
> properties of a bound service are modified through the
> ServiceRegistration.setProperties() method. This is a misbehaviour  
> which
> has been fixed in 1.4.0.

We're not using service properties, so I don't think that's the culprit.

Kris

> Regards
> Felix
>
> Kris Pruden schrieb:
>>
>> On Dec 16, 2009, at 12:42 PM, Felix Meschberger wrote:
>>
>>> Hi,
>>>
>>> Kris Pruden schrieb:
>>>> Hi,
>>>>
>>>> I'm puzzling through some strange behaviour in my application  
>>>> related to
>>>> what appears to be a race and/or some weird interaction between  
>>>> services
>>>> registered via SCR and bundles trying to monitor these services  
>>>> via the
>>>> ServiceTracker API.
>>>>
>>>> I don't have any good theories at the moment, so I was hoping if I
>>>> described what I'm seeing it might job somebody's memory...
>>>>
>>>> Here's my situation.  I have an application made up of about a
>>>> half-dozen or so bundles, most (but not all) of which register  
>>>> their
>>>> services using DS/SCR.  I'm using pax:exam to run automated  
>>>> functional
>>>> tests for this application.  Unfortunately, my tests are not  
>>>> reliable -
>>>> they fail intermittently.  When there's a failure, it's always  
>>>> because
>>>> of an NPE on one of the SCR-injected @Reference attributes of a
>>>> service/component.  It's hard to tell for sure, but what looks  
>>>> like is
>>>> happening is this:
>>>> 1. The SCR starts and registers a component/service
>>>> 2. The functional test, which was waiting for that service to  
>>>> become
>>>> available, gets a reference to the service
>>>> 3. The SCR stops the service, then immediately starts and  
>>>> registers a
>>>> new instance of the service
>>>>
>>>> Unfortunately, at this point the test bundle now has a reference  
>>>> to the
>>>> "stopped" instance of the service, which has had all of its  
>>>> @Reference
>>>> fields set to null (hence the NPE).
>>>>
>>>> What I can't figure out is why this is happening.
>>>>
>>>> Anyone have any suggestions about where I should look next, or  
>>>> any known
>>>> SCR gotchas that I might be running into?
>>>
>>> Well, from far outside, it must be said, that a service may come  
>>> and go
>>> at any time for any reason...
>>>
>>> Now, this doesn't help you, of course. But without a more in-depth  
>>> look
>>> into the situation I cannot tell much, other than: It should work
>>> actually.
>>>
>>> Let me quickly recapitulate:
>>>
>>> Your component under test is a SCR component which also is  
>>> registered as
>>> a service: Is this a delayed service component or a service factory
>>> component ?
>>
>> It's not a factory, and it is configured to start immediately.  These
>> are the annotations on the service in question:
>>
>> @Component(immediate=true)
>> @Service
>>
>>> SCR stops and immediately restarts the service: Are you updating
>>> configuration admin configuration supplied to the component during  
>>> the
>>> test ?
>>
>> Not as far as I know.  I should point out that I'm not 100% sure  
>> that my
>> claim of the start/stop/start behaviour is in fact true.  I see  
>> evidence
>> that this happens - I've seen log output from the SCR announcing the
>> activation of a component, then another message indicating that it's
>> deactivated, then another one saying it's activated again.  I've
>> instrumented the activate/deactivate methods on the service
>> implementation and confirmed that this is in fact happening, and that
>> the second activation is a new instance of the service class.   
>> However,
>> even in cases where I don't see this happening, I still am seeing the
>> NPE from time to time (more on this).
>>
>>> You talk about a @Reference annotation: Does this mean the SCR  
>>> component
>>> under test has a reference to another service ? Is this reference
>>> mandatory or optional ? Is it static or dynamic ? Is there a  
>>> change in
>>> the referenced service during the test ?
>>
>> Yes, so to be a bit more concrete I have the service my functional  
>> test
>> is exercising, call it ServiceA.  This service is annotated as  
>> above and
>> contains a dependency on a second service, ServiceB.  The class
>> definition looks something like this:
>>
>> @Component(immediate=true)
>> @Service
>> public class ServiceAImpl implements ServiceA {
>>    @Reference
>>    ServiceB serviceB;
>>
>>    ...
>> }
>>
>> ServiceB is similarly defined, and (maybe this is relevant) has its  
>> own
>> dependencies on other services, also injected via the @Reference
>> annotation as above, but at least one of these is not itself  
>> managed via
>> SCR (that is, it's a regular old service registered via a bundle
>> activator).  Further (again, not sure if it's relevant), this non-DS
>> service is actually provided via a ServiceFactory...
>>
>>> Last but not least: What DS implementation are you using ? Or: what
>>> version of Felix SCR are you using ?
>>
>> We're using Felix SCR 1.2.0.
>>
>> One other data point: I'm pretty sure the issue is at least somewhat
>> timing related.  The reason is that I have tried the build on two
>> separate computers, one a (relatively) slow laptop (a macbook pro),  
>> the
>> other a quite powerful workstation (quad-core, 8GB RAM, running  
>> linux).
>> The tests reliably *pass* on the slow laptop, but fairly reliably
>> *fails* on the fast machine.  My theory is that the fast machine is
>> winning the race against SCR in this start/stop/start loop (and
>> therefore losing) while the slow machine is losing that race...
>>
>> I'm still running experiments; I'll update with any new data I find  
>> that
>> I think might be helpful.  I realize issues like this are hard  
>> enough to
>> figure out when you're watching them happen, so I don't really expect
>> you to know what's going on here (although if you do that would be
>> awesome).  Mostly I'm just wondering if this setup is tickling a  
>> known
>> timing issue or something along those lines...
>>
>> Thanks again,
>>
>> Kris
>>
>>> Regards
>>> Felix
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: SCR interaction with ServiceTracker

Posted by Felix Meschberger <fm...@gmail.com>.
Hi,

Thanks for the update.

I have to admit, that I cannot tell what's going on.

>From the POV of SCR it doesn't matter whether a service used to satisfy
a reference is registered through a regular Bundle Activator or through
SCR -- in fact SCR doesn't even know.

Now, I think I have added fairly extensive logging information in SCR
1.2.0 (or at least I have done in the currently voted on 1.4.0 release
candidate) -- logging mostly done at DEBUG level. This logging should
indicate why SCR is taking down a component (and reactivating it).

Generally a component is reactivated if a statically bound reference has
to be replaced (because the bound reference is unregistered).

Also SCR 1.2.0 reactivates a component if service registration
properties of a bound service are modified through the
ServiceRegistration.setProperties() method. This is a misbehaviour which
has been fixed in 1.4.0.

Regards
Felix

Kris Pruden schrieb:
> 
> On Dec 16, 2009, at 12:42 PM, Felix Meschberger wrote:
> 
>> Hi,
>>
>> Kris Pruden schrieb:
>>> Hi,
>>>
>>> I'm puzzling through some strange behaviour in my application related to
>>> what appears to be a race and/or some weird interaction between services
>>> registered via SCR and bundles trying to monitor these services via the
>>> ServiceTracker API.
>>>
>>> I don't have any good theories at the moment, so I was hoping if I
>>> described what I'm seeing it might job somebody's memory...
>>>
>>> Here's my situation.  I have an application made up of about a
>>> half-dozen or so bundles, most (but not all) of which register their
>>> services using DS/SCR.  I'm using pax:exam to run automated functional
>>> tests for this application.  Unfortunately, my tests are not reliable -
>>> they fail intermittently.  When there's a failure, it's always because
>>> of an NPE on one of the SCR-injected @Reference attributes of a
>>> service/component.  It's hard to tell for sure, but what looks like is
>>> happening is this:
>>> 1. The SCR starts and registers a component/service
>>> 2. The functional test, which was waiting for that service to become
>>> available, gets a reference to the service
>>> 3. The SCR stops the service, then immediately starts and registers a
>>> new instance of the service
>>>
>>> Unfortunately, at this point the test bundle now has a reference to the
>>> "stopped" instance of the service, which has had all of its @Reference
>>> fields set to null (hence the NPE).
>>>
>>> What I can't figure out is why this is happening.
>>>
>>> Anyone have any suggestions about where I should look next, or any known
>>> SCR gotchas that I might be running into?
>>
>> Well, from far outside, it must be said, that a service may come and go
>> at any time for any reason...
>>
>> Now, this doesn't help you, of course. But without a more in-depth look
>> into the situation I cannot tell much, other than: It should work
>> actually.
>>
>> Let me quickly recapitulate:
>>
>> Your component under test is a SCR component which also is registered as
>> a service: Is this a delayed service component or a service factory
>> component ?
> 
> It's not a factory, and it is configured to start immediately.  These
> are the annotations on the service in question:
> 
> @Component(immediate=true)
> @Service
> 
>> SCR stops and immediately restarts the service: Are you updating
>> configuration admin configuration supplied to the component during the
>> test ?
> 
> Not as far as I know.  I should point out that I'm not 100% sure that my
> claim of the start/stop/start behaviour is in fact true.  I see evidence
> that this happens - I've seen log output from the SCR announcing the
> activation of a component, then another message indicating that it's
> deactivated, then another one saying it's activated again.  I've
> instrumented the activate/deactivate methods on the service
> implementation and confirmed that this is in fact happening, and that
> the second activation is a new instance of the service class.  However,
> even in cases where I don't see this happening, I still am seeing the
> NPE from time to time (more on this).
> 
>> You talk about a @Reference annotation: Does this mean the SCR component
>> under test has a reference to another service ? Is this reference
>> mandatory or optional ? Is it static or dynamic ? Is there a change in
>> the referenced service during the test ?
> 
> Yes, so to be a bit more concrete I have the service my functional test
> is exercising, call it ServiceA.  This service is annotated as above and
> contains a dependency on a second service, ServiceB.  The class
> definition looks something like this:
> 
> @Component(immediate=true)
> @Service
> public class ServiceAImpl implements ServiceA {
>     @Reference
>     ServiceB serviceB;
> 
>     ...
> }
> 
> ServiceB is similarly defined, and (maybe this is relevant) has its own
> dependencies on other services, also injected via the @Reference
> annotation as above, but at least one of these is not itself managed via
> SCR (that is, it's a regular old service registered via a bundle
> activator).  Further (again, not sure if it's relevant), this non-DS
> service is actually provided via a ServiceFactory...
> 
>> Last but not least: What DS implementation are you using ? Or: what
>> version of Felix SCR are you using ?
> 
> We're using Felix SCR 1.2.0.
> 
> One other data point: I'm pretty sure the issue is at least somewhat
> timing related.  The reason is that I have tried the build on two
> separate computers, one a (relatively) slow laptop (a macbook pro), the
> other a quite powerful workstation (quad-core, 8GB RAM, running linux). 
> The tests reliably *pass* on the slow laptop, but fairly reliably
> *fails* on the fast machine.  My theory is that the fast machine is
> winning the race against SCR in this start/stop/start loop (and
> therefore losing) while the slow machine is losing that race...
> 
> I'm still running experiments; I'll update with any new data I find that
> I think might be helpful.  I realize issues like this are hard enough to
> figure out when you're watching them happen, so I don't really expect
> you to know what's going on here (although if you do that would be
> awesome).  Mostly I'm just wondering if this setup is tickling a known
> timing issue or something along those lines...
> 
> Thanks again,
> 
> Kris
> 
>> Regards
>> Felix
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: SCR interaction with ServiceTracker

Posted by Kris Pruden <kp...@gmail.com>.
On Dec 16, 2009, at 12:42 PM, Felix Meschberger wrote:

> Hi,
>
> Kris Pruden schrieb:
>> Hi,
>>
>> I'm puzzling through some strange behaviour in my application  
>> related to
>> what appears to be a race and/or some weird interaction between  
>> services
>> registered via SCR and bundles trying to monitor these services via  
>> the
>> ServiceTracker API.
>>
>> I don't have any good theories at the moment, so I was hoping if I
>> described what I'm seeing it might job somebody's memory...
>>
>> Here's my situation.  I have an application made up of about a
>> half-dozen or so bundles, most (but not all) of which register their
>> services using DS/SCR.  I'm using pax:exam to run automated  
>> functional
>> tests for this application.  Unfortunately, my tests are not  
>> reliable -
>> they fail intermittently.  When there's a failure, it's always  
>> because
>> of an NPE on one of the SCR-injected @Reference attributes of a
>> service/component.  It's hard to tell for sure, but what looks like  
>> is
>> happening is this:
>> 1. The SCR starts and registers a component/service
>> 2. The functional test, which was waiting for that service to become
>> available, gets a reference to the service
>> 3. The SCR stops the service, then immediately starts and registers a
>> new instance of the service
>>
>> Unfortunately, at this point the test bundle now has a reference to  
>> the
>> "stopped" instance of the service, which has had all of its  
>> @Reference
>> fields set to null (hence the NPE).
>>
>> What I can't figure out is why this is happening.
>>
>> Anyone have any suggestions about where I should look next, or any  
>> known
>> SCR gotchas that I might be running into?
>
> Well, from far outside, it must be said, that a service may come and  
> go
> at any time for any reason...
>
> Now, this doesn't help you, of course. But without a more in-depth  
> look
> into the situation I cannot tell much, other than: It should work  
> actually.
>
> Let me quickly recapitulate:
>
> Your component under test is a SCR component which also is  
> registered as
> a service: Is this a delayed service component or a service factory
> component ?

It's not a factory, and it is configured to start immediately.  These  
are the annotations on the service in question:

@Component(immediate=true)
@Service

> SCR stops and immediately restarts the service: Are you updating
> configuration admin configuration supplied to the component during the
> test ?

Not as far as I know.  I should point out that I'm not 100% sure that  
my claim of the start/stop/start behaviour is in fact true.  I see  
evidence that this happens - I've seen log output from the SCR  
announcing the activation of a component, then another message  
indicating that it's deactivated, then another one saying it's  
activated again.  I've instrumented the activate/deactivate methods on  
the service implementation and confirmed that this is in fact  
happening, and that the second activation is a new instance of the  
service class.  However, even in cases where I don't see this  
happening, I still am seeing the NPE from time to time (more on this).

> You talk about a @Reference annotation: Does this mean the SCR  
> component
> under test has a reference to another service ? Is this reference
> mandatory or optional ? Is it static or dynamic ? Is there a change in
> the referenced service during the test ?

Yes, so to be a bit more concrete I have the service my functional  
test is exercising, call it ServiceA.  This service is annotated as  
above and contains a dependency on a second service, ServiceB.  The  
class definition looks something like this:

@Component(immediate=true)
@Service
public class ServiceAImpl implements ServiceA {
     @Reference
     ServiceB serviceB;

     ...
}

ServiceB is similarly defined, and (maybe this is relevant) has its  
own dependencies on other services, also injected via the @Reference  
annotation as above, but at least one of these is not itself managed  
via SCR (that is, it's a regular old service registered via a bundle  
activator).  Further (again, not sure if it's relevant), this non-DS  
service is actually provided via a ServiceFactory...

> Last but not least: What DS implementation are you using ? Or: what
> version of Felix SCR are you using ?

We're using Felix SCR 1.2.0.

One other data point: I'm pretty sure the issue is at least somewhat  
timing related.  The reason is that I have tried the build on two  
separate computers, one a (relatively) slow laptop (a macbook pro),  
the other a quite powerful workstation (quad-core, 8GB RAM, running  
linux).  The tests reliably *pass* on the slow laptop, but fairly  
reliably *fails* on the fast machine.  My theory is that the fast  
machine is winning the race against SCR in this start/stop/start loop  
(and therefore losing) while the slow machine is losing that race...

I'm still running experiments; I'll update with any new data I find  
that I think might be helpful.  I realize issues like this are hard  
enough to figure out when you're watching them happen, so I don't  
really expect you to know what's going on here (although if you do  
that would be awesome).  Mostly I'm just wondering if this setup is  
tickling a known timing issue or something along those lines...

Thanks again,

Kris

> Regards
> Felix
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: SCR interaction with ServiceTracker

Posted by Felix Meschberger <fm...@gmail.com>.
Hi,

Kris Pruden schrieb:
> Hi,
> 
> I'm puzzling through some strange behaviour in my application related to
> what appears to be a race and/or some weird interaction between services
> registered via SCR and bundles trying to monitor these services via the
> ServiceTracker API.
> 
> I don't have any good theories at the moment, so I was hoping if I
> described what I'm seeing it might job somebody's memory...
> 
> Here's my situation.  I have an application made up of about a
> half-dozen or so bundles, most (but not all) of which register their
> services using DS/SCR.  I'm using pax:exam to run automated functional
> tests for this application.  Unfortunately, my tests are not reliable -
> they fail intermittently.  When there's a failure, it's always because
> of an NPE on one of the SCR-injected @Reference attributes of a
> service/component.  It's hard to tell for sure, but what looks like is
> happening is this:
> 1. The SCR starts and registers a component/service
> 2. The functional test, which was waiting for that service to become
> available, gets a reference to the service
> 3. The SCR stops the service, then immediately starts and registers a
> new instance of the service
> 
> Unfortunately, at this point the test bundle now has a reference to the
> "stopped" instance of the service, which has had all of its @Reference
> fields set to null (hence the NPE).
> 
> What I can't figure out is why this is happening.
> 
> Anyone have any suggestions about where I should look next, or any known
> SCR gotchas that I might be running into?

Well, from far outside, it must be said, that a service may come and go
at any time for any reason...

Now, this doesn't help you, of course. But without a more in-depth look
into the situation I cannot tell much, other than: It should work actually.

Let me quickly recapitulate:

Your component under test is a SCR component which also is registered as
a service: Is this a delayed service component or a service factory
component ?

SCR stops and immediately restarts the service: Are you updating
configuration admin configuration supplied to the component during the
test ?

You talk about a @Reference annotation: Does this mean the SCR component
under test has a reference to another service ? Is this reference
mandatory or optional ? Is it static or dynamic ? Is there a change in
the referenced service during the test ?

Last but not least: What DS implementation are you using ? Or: what
version of Felix SCR are you using ?

Regards
Felix


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org