[ 
https://issues.apache.org/jira/browse/FELIX-1841?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12773406#action_12773406
 ] 

Pierre De Rop commented on FELIX-1841:
--------------------------------------

Ok. I do agree;

Just calling back the "Client" in its bind method, when the "Service" 
properties are modified sounds like to be enough, and as you said, we don't 
really want to reactivate the "Client ...

I checked in the specification, but I did not find anything regarding this 
issue. 
I think that this use case is a sub-set of the "bound service replacement" 
feature: the "bind" is called with the same service, but not the "unbind" ...

For now, we'll use my patch in our application server, because, well, we really 
need it.

thanks;
/pierre


> 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
>         Attachments: DependencyManager.java
>
>
> 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