Community
Participate
Working Groups
Created attachment 259731 [details] test application Consider an application model with a PartStack and a fragment that contributes a Part to that PartStack, configured to be applied as "notexists" (so, only if the contributed elements are not already part of the application model). The expectation would be that the contributed part will not be added to the PartStack if the stack already contains an element with the same element id. However, it seems that the elements from the fragment will always be merged and will replace the ones from the application model. To test this you can use the attached application that contains: - the application model with a PartStack and a Part (part1) - a fragment that contributes the same part1 to the application's PartStack (same elementId and even the same resource xmi id) only if it doesn't exist (notexists) - a pre-processor (Processor1) that adds a new value to part1's persisted state - a post-processor (Processor2) that reads part1's persisted state The expectation would be that part1's persisted state still contains the value set by the pre-processor even after the fragments are merged. However, this is not the case, as part1 gets replaced by the element contributed by the fragment. Even if if part1 is not manually added to the application model, but initially contributed by the fragment, and the application model is then loaded from the persisted state, the results are the same. The problem seems to be caused by the ModelUtils#mergeList method that is being used for merging the elements contributed by the fragment. The method checks if the application model contains an element with the same id as the one we are trying to merge and at the same time checks if the app model element is _equal_ to the element we want to merge. Only if both conditions are satisfied, the fragment element is not merged. Moreover, the code does not care at this point under what conditions the fragment element was contributed (notexists, always etc.). The equality check is performed using EcoreUtil#equals(object1, object2), which will always return false when comparing a model element with a fragment element, because the elements have different parents: one is contained in the application model, while the the other in the model fragment.
Thank you for the diagnosis! Could you please provide a patch? https://wiki.eclipse.org/Platform_UI/How_to_Contribute
we will do...
Is there any news on this? I found another issue with the ModelUtils#mergeList method. In the last else branch labelled "replace" it uses the UsageCrossReferencer#find to find references to the replaced object. The list of settings returned by the UsageCrossReferencer may contain a Setting that is actually a list. Calling Setting#set on a list results in a class cast exception. See also attached debugger screenshots. java.lang.ClassCastException: org.eclipse.e4.ui.model.application.commands.impl.BindingContextImpl cannot be cast to java.util.List at org.eclipse.emf.ecore.util.EcoreEList.set(EcoreEList.java:457) at org.eclipse.e4.ui.model.internal.ModelUtils.mergeList(ModelUtils.java:189) at org.eclipse.e4.ui.model.internal.ModelUtils.merge(ModelUtils.java:145) at org.eclipse.e4.ui.model.fragment.impl.StringModelFragmentImpl.mergeIdList(StringModelFragmentImpl.java:322) at org.eclipse.e4.ui.model.fragment.impl.StringModelFragmentImpl.merge(StringModelFragmentImpl.java:300) at org.eclipse.e4.ui.internal.workbench.ModelAssembler.processModelFragment(ModelAssembler.java:272) at org.eclipse.e4.ui.internal.workbench.ModelAssembler.processFragmentConfigurationElement(ModelAssembler.java:162) at org.eclipse.e4.ui.internal.workbench.ModelAssembler.processFragments(ModelAssembler.java:118) at org.eclipse.e4.ui.internal.workbench.ModelAssembler.processModel(ModelAssembler.java:96) at org.eclipse.e4.ui.internal.workbench.ResourceHandler.loadMostRecentModel(ResourceHandler.java:197) at org.eclipse.e4.ui.internal.workbench.swt.E4Application.loadApplicationModel(E4Application.java:377) at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:252) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:632) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) at esa.open.application.Application.start(Application.java:55) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) at org.eclipse.equinox.launcher.Main.run(Main.java:1519) at org.eclipse.equinox.launcher.Main.main(Main.java:1492)
Created attachment 271774 [details] Class cast exception in ModelUtils.mergeList() Debugger screenshot 1
Created attachment 271775 [details] Class cast exception in ModelUtils.mergeList() Debugger screenshot 2
*** Bug 547503 has been marked as a duplicate of this bug. ***
The problem is not really in ModelUtils#mergeList The root cause is in ModelAssembler#processModelFragment, it does check if the element is already applied: if (checkExist && applicationResource.getIDToEObjectMap().containsKey(r.getID(o))) { continue; } However, at the end of the method, the fragment is merge unconditionally. return fragment.merge(application);
(In reply to Wernke zur Borg from comment #3) I created Bug 547839 for this separate issue.
*** This bug has been marked as a duplicate of bug 440030 ***