Bug 528165 - IllegalStateException thrown when generating modelpatch on a comparison with a metamodel containing a multi-valued attribute
Summary: IllegalStateException thrown when generating modelpatch on a comparison with ...
Status: RESOLVED FIXED
Alias: None
Product: EMF.Diffmerge
Classification: Modeling
Component: Patch (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 blocker (vote)
Target Milestone: ---   Edit
Assignee: Abel Hegedus CLA
QA Contact: Olivier Constant CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-12-05 10:49 EST by Vincent HEMERY CLA
Modified: 2017-12-06 00:00 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent HEMERY CLA 2017-12-05 10:49:24 EST
This bug occurs with version 0.1.0 or EMF Patch available on 2017-10-27 16:26 at :
https://hudson.eclipse.org/diffmerge/job/emf-diffmerge-patch-master/lastSuccessfulBuild/artifact/releng/org.eclipse.emf.diffmerge.patch.update/target/repository
... and it should still occur today on the trunk given the look I had on the git repository.


I have a metamodel with EClasses containing multi-valued EAttributes. On the concerned EAttribute, upper bound is -1, default value literal is not set and getDefaultValue() returns null.

After successfully making a model diff, I try generating the model patch.
The patch generation fails and prints an error dialog with exception :
"java.lang.IllegalStateException: The object is not found in the containing list."

Here's what occurs in the
org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.saveAllAttribute(EObject, ModelPatchBuilder, ModelPatchEntryBuilder) method :

    for(eAttr : element.eClass.EAllAttributes.filter[!it.isID]) {
      // eGet returns me an empty EList, because my eAttr is multi-valued
      val value = element.eGet(eAttr)
      if(value !== null && (eAttr.defaultValue === null || eAttr.defaultValue != value)) {
        // we get here because value is not null (empty EList) and default (single) value is null
        // indexOf fails with the IllegalStateException because it is searching for the empty EList in the list of values
        val index = element.indexOf(value, eAttr)
        val addedAttributeEntry = (entryBuilder => [
          it.feature = new Identifiable(eAttr.identify)
          it.value = EcoreUtil.convertToString(eAttr.getEAttributeType(), value);
          it.index = index
        ]).buildAttributeEntry
        patchBuilder.addNewEntry(addedAttributeEntry)
      }
    }

Maybe just testing with if(!element.eIsSet(eAttr)) instead would fix the bug, but I'm not sure of the other implications it may have...
Please, let me know in case you encounter any difficulty in reproducing the bug. I did not attach my full context because there is too much other stuff around it, but making a simple one-class metamodel should be enough to reproduce it.


The complete stack is :
java.lang.IllegalStateException: The object is not found in the containing list.
The object is not found in the containing list.
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.indexOf(ModelPatchRecorder.java:403)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.saveAllAttribute(ModelPatchRecorder.java:622)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder._processDifference(ModelPatchRecorder.java:579)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.processDifference(ModelPatchRecorder.java:744)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.processDifference(ModelPatchRecorder.java:328)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.access$0(ModelPatchRecorder.java:323)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder$2.apply(ModelPatchRecorder.java:279)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder$2.apply(ModelPatchRecorder.java:1)
  org.eclipse.xtext.xbase.lib.IteratorExtensions.forEach(IteratorExtensions.java:385)
  org.eclipse.xtext.xbase.lib.IterableExtensions.forEach(IterableExtensions.java:351)
  org.eclipse.emf.diffmerge.patch.runtime.ModelPatchRecorder.generateModelPatch(ModelPatchRecorder.java:282)
  org.eclipse.emf.diffmerge.patch.ui.handlers.ModelpatchGenerationHandler.generatePatch(ModelpatchGenerationHandler.java:127)
  org.eclipse.emf.diffmerge.patch.ui.handlers.ModelpatchGenerationHandler.execute(ModelpatchGenerationHandler.java:93)
  org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:291)
  org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:92)
  sun.reflect.GeneratedMethodAccessor48.invoke(Unknown Source)
  sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  java.lang.reflect.Method.invoke(Unknown Source)
  org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
  org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:305)
  org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:239)
  org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:132)
  org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:152)
  org.eclipse.core.commands.Command.executeWithChecks(Command.java:494)
  org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:487)
  org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:210)
  org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:431)
  org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:446)
  org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:472)
  org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem$$Lambda$171/14296119.handleEvent(Unknown Source)
  org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86)
  org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428)
  org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079)
  org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238)
  org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817)
  org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1150)
  org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
  org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1039)
  org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
  org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680)
  org.eclipse.ui.internal.Workbench$$Lambda$14/21988119.run(Unknown Source)
  org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
  org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594)
  org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
  org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151)
  org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
  org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
  org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
  org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
  org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  java.lang.reflect.Method.invoke(Unknown Source)
  org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653)
  org.eclipse.equinox.launcher.Main.basicRun(Main.java:590)
  org.eclipse.equinox.launcher.Main.run(Main.java:1499)
  org.eclipse.equinox.launcher.Main.main(Main.java:1472)
Comment 1 Abel Hegedus CLA 2017-12-05 10:54:22 EST
Thanks for the report! I will take a look at it.
Comment 2 Abel Hegedus CLA 2017-12-05 11:44:04 EST
Based on your nice, detailed report, I was able to easily create some tests (the CPS metamodel we use for all tests has a multi-value attribute) to reproduce the problem and then fix the implementation.

You can see the changes in https://git.eclipse.org/r/112889 and test the fix by updating from the latest CI repository you linked.
Comment 3 Eclipse Genie CLA 2017-12-06 00:00:35 EST
New Gerrit change created: https://git.eclipse.org/r/112889