SCR invokes bind method twice when dependency service properties are modified
-----------------------------------------------------------------------------

                 Key: FELIX-1841
                 URL: https://issues.apache.org/jira/browse/FELIX-1841
             Project: Felix
          Issue Type: Bug
          Components: Declarative Services (SCR)
            Reporter: Pierre De Rop
            Priority: Minor


It seems that when a service S is depending on another service D, and when D 
service properties are modified (using ServiceRegistration.setProperties 
method), then D is 
re-bound twice into the using service S.

For example, I have a service "Client" has a "1..1" dependency over "Service":

<?xml version="1.0" encoding="UTF-8"?>
<component name="Client">
  <implementation class="client.Client"/>
  <reference name="SERVICE" 
    interface="service.Service"
    policy="dynamic"
    cardinality="1..1"
    target="(foo=bar)"
    bind="bind"/>
</component>

public class Client {
  protected void bind(Service s) {
    System.out.println("Client:: bound Service : " + s);
    Thread.dumpStack();
  }
}



I have another bundle which provide the "Service" dependency, and sometimes, 
the "Service" properties are modified like this:

        ServiceRegistration reg ...
        reg.setProperties(...)
 
So, when the setProperties takes place, "Client" is re-bound twice with the 
service "Service".
Indeed, in DependencyManager, when a ServiceEvent.MODIFIED event. is caught, 
the following code is invoked (line 170):


            case ServiceEvent.MODIFIED:
                m_componentManager.log( LogService.LOG_DEBUG, "Dependency 
Manager: Updating {0}", new Object[]
                    { serviceString }, null );

                // remove the service first
                // only continue with further event handling if the service
                // removal did not cause the component to be deactivated
                if ( serviceRemoved( ref ) )
                {
                    // recalculate the number of services matching the filter
                    // because we don't know whether this service previously 
matched
                    // or not
                    ServiceReference refs[] = getFrameworkServiceReferences();
                    m_size = ( refs == null ) ? 0 : refs.length;

                    // now try to bind the service - if it matches the target 
filter
                    // without recalculating the size (already done).
                    if ( targetFilterMatch( ref ) )
                    {
                        serviceAdded( ref );
                    }
                }

                break;

So, the service is first re-bound to the Client, when the serviceRemoved() 
method is invoked (it's a bound service replacement, I guess).
But the problem here is that the modified service is also re-bound, when 
serviceAdded is invoked (line 189).
Don't you think that this is a bug and the service should be re-bound only 
once, not twice ?

Here is the first stacktrace of the first bind:

java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1158)
        at client.Client.bind(Client.java:13)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:213)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:38)
        at 
org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:542)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:434)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.invokeBindMethod(DependencyManager.java:948)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.bind(DependencyManager.java:884)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.serviceRemoved(DependencyManager.java:367)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.serviceChanged(DependencyManager.java:177)
        at 
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:878)
        at 
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:732)
        at 
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:662)
        at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3587)
        at org.apache.felix.framework.Felix.access$000(Felix.java:40)
        at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:625)
        at 
org.apache.felix.framework.ServiceRegistry.servicePropertiesModified(ServiceRegistry.java:505)
        at 
org.apache.felix.framework.ServiceRegistrationImpl.setProperties(ServiceRegistrationImpl.java:116)
        at service.impl.ServiceFactory.run(ServiceFactory.java:48)
        at java.lang.Thread.run(Thread.java:595)

and here is the second stacktrace, when Service is re-bound:

Client: bound Service : service.impl.servicei...@142a80d
java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1158)
        at client.Client.bind(Client.java:13)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:213)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:38)
        at 
org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:542)
        at 
org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:434)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.invokeBindMethod(DependencyManager.java:948)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.serviceAdded(DependencyManager.java:271)
        at 
org.apache.felix.scr.impl.manager.DependencyManager.serviceChanged(DependencyManager.java:189)
        at 
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:878)
        at 
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:732)
        at 
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:662)
        at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3587)
        at org.apache.felix.framework.Felix.access$000(Felix.java:40)
        at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:625)
        at 
org.apache.felix.framework.ServiceRegistry.servicePropertiesModified(ServiceRegistry.java:505)
        at 
org.apache.felix.framework.ServiceRegistrationImpl.setProperties(ServiceRegistrationImpl.java:116)
        at service.impl.ServiceFactory.run(ServiceFactory.java:48)
        at java.lang.Thread.run(Thread.java:595)


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to