Uploaded image for project: 'Felix'
  1. Felix
  2. FELIX-1841

SCR invokes bind method twice when dependency service properties are modified

    XMLWordPrintableJSON

Details

    Description

      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.ServiceImpl@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)

      Attachments

        1. FELIX-1841.patch.2
          5 kB
          Pierre De Rop
        2. FELIX-1841.patch
          3 kB
          Felix Meschberger
        3. DependencyManager.java
          44 kB
          Pierre De Rop

        Issue Links

          Activity

            People

              fmeschbe Felix Meschberger
              pderop Pierre De Rop
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: