You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Felix Meschberger (JIRA)" <ji...@apache.org> on 2010/07/30 13:42:16 UTC

[jira] Closed: (FELIX-1841) SCR invokes bind method twice when dependency service properties are modified

     [ https://issues.apache.org/jira/browse/FELIX-1841?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Felix Meschberger closed FELIX-1841.
------------------------------------


Closing since version is released.

> 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)
>    Affects Versions: scr-1.2.0
>            Reporter: Pierre De Rop
>            Assignee: Felix Meschberger
>            Priority: Minor
>             Fix For:  scr-1.4.0
>
>         Attachments: DependencyManager.java, FELIX-1841.patch, FELIX-1841.patch.2
>
>
> 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)

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