[ https://issues.apache.org/jira/browse/FELIX-5453?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15762703#comment-15762703 ]
Pierre De Rop commented on FELIX-5453: -------------------------------------- Hi Jeroen; So I took a look into your example. I think there is no bug per se, and your intuition is correct: Indeed when you remove aspect1, the ServiceRequiringX is not called in its swapped callback because it is still bound to the aspect2. However, at the point when you remove aspect1, it is the aspect2 which is swapped with the original service XImpl. (before your removed aspec1, aspect2 was bound to aspect1). If you want the aspect2 to know that is it swapped with the original service (if this is what you would like to achieve), then it is possible to define the swap callback on the aspect2 itself. For example: {code} Component aspect2 = manager.createAspectService(X.class, null, 200, "set", null, null, "swap") .setImplementation(Aspect2.class); manager.add(aspect2); {code} Also, I would like to say that I noticed from your Activator that you called "setCallbacks(null, null, null, null)" method on the aspect components like this: {code} Component aspect2 = manager.createAspectService(X.class, null, 200) .setImplementation(Aspect2.class).setCallbacks(null, null, null, null); manager.add(aspect2); {code} but here, the setCallbacks method is used for lifecycle callbacks ("init", "start", "stop", "destroy") method. If you need to specify "add","change","remove","swap" callbacks, then you have to invoke the createAspectService with the "add","change","remove","swap" callback signatures (see http://felix.apache.org/apidocs/dependencymanager/r7/org/apache/felix/dm/DependencyManager.html#createAspectService-java.lang.Class-java.lang.String-int-java.lang.String-java.lang.String-java.lang.String-java.lang.String-) Now, if what you would like to achieve is allow the ServiceRequiringX to detect itself that the aspect2 is swapped with the lower ranked aspect1, then I think it is not directly possible using the DM api because when you create the service dependency, the highest ranked service is injected, and if one lower ranked aspect is removed, the aspect which is on top of the removed aspect will be the only one which will be swapped, not the ServiceRequiringX (which will remain bound to aspect2). But there is a work around: if your ServiceRequiringX really need to detect swap events for aspects of X, then you can use the DM ServiceTracker. This class is the same as the osgi ServiceTracker, except that it has an open method which allows to detect all added/changed/removed aspects for a given service. So, you can then create such tracker from the ServiceRequiringX.init() method, and make your ServiceRequiringX implements the ServiceTrackerCustomizerInterface. I'm not sure why you would need to do this, but can you take a look at the attached Activator2 sample code ? I just modified your original Activator in order to use the DM ServiceTracker in order to detect if lower ranked aspect are swapped. Notice that the filter used contains "DependencyManager.ASPECT=*" because all DM aspects contain such property. In the Activator2, I also configured the aspects so they are called in their swap callbacks. (not sure if you need this ?) So, using the Activator2, you will see the following logs: {code} Add: XImpl Swap old: XImpl, new: Aspect1 Tracker: add: Aspect1 Swap old: Aspect1, new: Aspect2 Tracker: add: Aspect2 Tracker: remove: Aspect1 Aspect2 swapped: old=Aspect1, new=XImpl Swap old: Aspect2, new: XImpl Tracker: remove: Aspect2 {code} So, when the aspect1 is removed, the tracker will detect that the aspect1 is removed (check "Tracker: remove: Aspect1" log), and the Aspect2.swap method will be invoked (check "Aspect2 swapped: old=Aspect1, new=XImpl" log). Let me know if Activator2 sample code helps ? Does it do what you are trying to achieve ? > Swap callback not called when there are multiple aspects on a service and one > of the aspects with lower rank is removed > ----------------------------------------------------------------------------------------------------------------------- > > Key: FELIX-5453 > URL: https://issues.apache.org/jira/browse/FELIX-5453 > Project: Felix > Issue Type: Bug > Components: Dependency Manager > Affects Versions: org.apache.felix.dependencymanager-r8 > Reporter: Jeroen Daanen > Attachments: Activator.java, Activator2.java > > > If you have multiple aspects on a service with interface X and one of the > aspects with a lower rank is removed, the service requiring service X does > not get the swap callback. > See the attached Activator with example code. > The swap method is not called when 'aspect1' is removed. > Actual output of running the activator: > {noformat} > Add: XImpl > Swap old: XImpl > Swap new: Aspect1 > Swap old: Aspect1 > Swap new: Aspect2 > Swap old: Aspect2 > Swap new: XImpl > {noformat} > I can understand why swap is not called, because for ServiceRequiringX > Aspect1 does not get really 'swapped' (the service stays Aspect2) But is > there any way to find out this is happening? -- This message was sent by Atlassian JIRA (v6.3.4#6332)