viatra / EMF-IncQuery

This repository is only kept for historic reasons. All development happens on eclipse.org
http://eclipse.org/viatra
13 stars 4 forks source link

Duplicate deletion exception in SchoolTest #227

Closed csattila closed 12 years ago

csattila commented 12 years ago

SchoolTest projects: https://github.com/ujhelyiz/EMF-IncQuery-Examples/tree/master/school

When I run this test (delete a Course from the model):

@Test
    def deleteCourse(){
        val sns = snapshot
        val pm = queryInputEIQ
        pm.assertMatchResults(sns)

        // MODEL MODIFICATION HERE
        // delete the Course "Prolog programming"
        val matcher = pm.initializeMatcherFromModel(sns.EMFRootForSnapshot, "school.schools")
        val s = matcher.oneArbitraryMatch.get("Sch") as School
        Assert::assertNotNull(s)
        if (s!=null) {  
            val courses = s.courses 

            for(Course c : courses){
                if(c.subject == "Prolog programming"){
                    courses.remove(c)                                           
                }
            }   

            val newSns = sns.eResource.resourceSet.loadExpectedResultsFromUri("school.tests/model/tests_deleteCourse.eiqsnapshot")
            pm.assertMatchResults(newSns)               

        }               
    }

The following exception is encountered:

Duplicate deletion of T(school.impl.CourseImpl@1fe8bbe (subject: Prolog programming, weight: 23);school.impl.SchoolImpl@526d7a (name: Budapest University of Technology and Economics, address: 1117 Budapest, Magyar Tudosok krt 2.);) was detected in UniquenessEnforcer [10]UniquenessEnforcerNode[[org.eclipse.emf.ecore.impl.EReferenceImpl@3d7fcf (name: school) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: true, defaultValueLiteral: null, unsettable: false, derived: false) (containment: false, resolveProxies: false)]]
java.lang.NullPointerException
    at org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.TupleMemory.remove(TupleMemory.java:62)
    at org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.single.UniquenessEnforcerNode.update(UniquenessEnforcerNode.java:76)
    at org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.ReteContainer.messageConsumptionSingleThreaded(ReteContainer.java:489)
    at org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Network.waitForReteTermination(Network.java:321)
    at org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.boundary.ReteBoundary.updateBinaryEdge(ReteBoundary.java:621)
    at org.eclipse.viatra2.emf.incquery.runtime.internal.BaseIndexListener.featureDeleted(BaseIndexListener.java:129)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperContentAdapter.notifyFeatureListeners(NavigationHelperContentAdapter.java:454)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperContentAdapter.removeFeatureTuple(NavigationHelperContentAdapter.java:349)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperVisitor.visitReference(NavigationHelperVisitor.java:203)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperVisitor.visitNonContainmentReference(NavigationHelperVisitor.java:194)
    at org.eclipse.viatra2.emf.incquery.base.comprehension.EMFModelComprehension.visitFeatureInternal(EMFModelComprehension.java:168)
    at org.eclipse.viatra2.emf.incquery.base.comprehension.EMFModelComprehension.visitFeatureInternalSimple(EMFModelComprehension.java:136)
    at org.eclipse.viatra2.emf.incquery.base.comprehension.EMFModelComprehension.visitFeature(EMFModelComprehension.java:126)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperContentAdapter.featureUpdate(NavigationHelperContentAdapter.java:128)
    at org.eclipse.viatra2.emf.incquery.base.core.NavigationHelperContentAdapter.notifyChanged(NavigationHelperContentAdapter.java:99)
    at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
    at org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch(NotificationImpl.java:1027)
    at org.eclipse.emf.common.notify.impl.NotifyingListImpl.remove(NotifyingListImpl.java:718)
    at org.eclipse.emf.common.util.AbstractEList.remove(AbstractEList.java:460)
    at school.tests.SchoolTestsModelManipulation.deleteCourse(SchoolTestsModelManipulation.java:186)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.eclipse.xtext.junit4.XtextRunner$1.evaluate(XtextRunner.java:55)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
    at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
istvanrath commented 12 years ago

@csattila : it is not good practice to call .remove() while iterating in a foreach loop in Java. See http://stackoverflow.com/questions/1196586/calling-remove-in-foreach-loop-in-java for details.

Nevertheless, the RETE-level exception seems very much like a bug.

bergmanngabor commented 12 years ago

Works for me.

@csattila make sure you have an up-to-date version of EMF-IncQuery (a lot has changed on last Friday) and see if you can still observe this issue. If not, then the ticket should be closed. If you do still observe this exception, please push the version of the test where it occurs (including the instance model and queries if you have modified them as well).

bergmanngabor commented 12 years ago

OK, I nailed down the issue to a concurrency bug in ecore's own EContentAdapter, no less. Commited the work-around that seems to resolve this issue.

As a follow-up, I will have to submit a bug report or something to the EMF folks about ECoreUtil.

bergmanngabor commented 12 years ago

For the record, this is the upstream bug report:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=385039

istvanrath commented 12 years ago

Ed Merks has responded!