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

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

Felix,

I have tested the patch for this issue and for the other FELIX-1866 issue.
Indeed, when the service properties are changed, no re-bind is attempted at all.

But I am confused now and I realize that I did not initially state my problems 
clearly.
So, let me try to go to the right point and reformulate my problems:

I have two problems:

1) Using CM, When I update some public service properties (not starting with a 
"."), I would like to re-bind
the modified service to the other components which depend on it (just once, not 
twice)

2) When I update (using CM) only some private service properties (prefixed with 
a "."), then I would like to get my
component called in its "modified" callback but the component should not be 
re-bound to other 
components which depend on it, because the modified private properties are not 
supposed to be published 
(see 112.6.1, in spec, am I correct ?)

So, what do you think about the following strategy:

1) add a "else" in your patch in order to re-bind once:

                ...
                else if ( !targetFilterMatch( ref ) )
                {
                    m_size--;
                    serviceRemoved( ref );
                } else {
->                bind(); // -> re-bind once.
                }

2) in ImmediateComponentManager.java, around line 472 -> check if the 
properties modified from CM are private (start with a ".") and don't invoke 
"sr.setProperties( regProps )" if modified properties are private.

Does this make sense ?


> 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, FELIX-1841.patch
>
>
> 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