Brent Daniel created FELIX-6036:
-----------------------------------

             Summary: Race condition prevents optional/greedy ref setter method 
from being called
                 Key: FELIX-6036
                 URL: https://issues.apache.org/jira/browse/FELIX-6036
             Project: Felix
          Issue Type: Bug
          Components: Declarative Services (SCR)
    Affects Versions: scr-2.1.14
            Reporter: Brent Daniel


I have a component with an optional/dynamic/greedy reference. The target is 
registered directly with OSGi using BundleContext.registerService(). Normally, 
either SingleDynamicCustomizer.addedService() or 
SingleComponentManager.createImplementationObject() will succeed in binding the 
reference, but there is a race condition that can prevent the setter method 
from ever being called. 

 

The failure path is as follows:

1) SingleComponentManager.createImplementationObject calls open() on each of 
its DependencyManagers. This generates an OpenStatus where the RefPair list is 
empty because our target has not been registered yet. 

2) Before createImplementationObject() can set the component context, the 
customizer's addedService() method is called in response to the target service 
registration. It attempts to bind the target service, but that will not happen 
because the component context has not been set yet. 

3) createImplementationObject then creates the implementation, sets the 
component context, and goes through the list of OpenStatus objects to bind 
target services. The RefPair list for the OpenStatus object will still be 
empty, so we will not call the setter method for the reference we're concerned 
about. 

 

I'm not sure of a good way to fix this. I couldn't come up with a good approach 
using synchronization or earlier creation of the implementation object. At the 
moment I am working around this by refreshing the list of RefPairs in the 
OpenStatus object at the top of DependencyManager.bindDependency():
 
{code:java}
// Refresh ref list before binding
synchronized(m_tracker.tracked()) {
   status.refs=m_customizer.getRefs(status.trackingCount);
}
{code}
 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to