Bug 251544 - Instance of list are not the same for the following transition transient/new persisted/transient resulting strange behavior (NPE)
Summary: Instance of list are not the same for the following transition transient/new ...
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: M3   Edit
Assignee: Simon Mc Duff CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-21 10:43 EDT by Victor Roldan Betancort CLA
Modified: 2010-06-29 09:21 EDT (History)
3 users (show)

See Also:
stepper: galileo+
stepper: review+


Attachments
Patch v1 (41.88 KB, patch)
2008-10-21 19:37 EDT, Simon Mc Duff CLA
no flags Details | Diff
Patch v2 - with no testcase updated (43.35 KB, patch)
2008-10-22 11:41 EDT, Simon Mc Duff CLA
no flags Details | Diff
Patch v3 - Final (51.90 KB, patch)
2008-10-22 12:11 EDT, Simon Mc Duff CLA
no flags Details | Diff
Patch v4 - ready to be committed (57.09 KB, patch)
2008-10-27 03:16 EDT, Eike Stepper CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Victor Roldan Betancort CLA 2008-10-21 10:43:07 EDT
If a CDOObject is detached, it means eStore == null.

Now look at CDOStoreEList implementation: there are getStore().<xxx> calls in almost every method. NPE's all around.

Simon, could you tell me in which cases CDOStoreEList is used? I can't get to reproduce this bug... Only through CDOEditor.
Comment 1 Simon Mc Duff CLA 2008-10-21 11:16:41 EDT
Hi Victor,

CDOStoreEList is used only when CDOObject (its container) is not transient.
If the list is used when the eStore == null this means it is a problem.
Comment 2 Simon Mc Duff CLA 2008-10-21 11:21:48 EDT
Victor can you tell me what you are doing in the CDOEditor to reproduce it.
Comment 3 Victor Roldan Betancort CLA 2008-10-21 11:26:56 EDT
>> Victor can you tell me what you are doing in the CDOEditor to reproduce it.

The store is used by a EMF RemoveCommand in CDOEditor.
You can reproduce this bug by selecting a node and it's parent in the tree, and then deleting both at the same time.

This creates a CompoundCommand, composed by 2 RemoveCommands. If the parent's remove command is executed before the childrens', the RemoveCommand of the children will fail, because it tries to remove the children from the parent, but eStore is null!

I fixed it by adding NPE control in the CDOStoreEList methods, but I guess is not the way!
Comment 4 Simon Mc Duff CLA 2008-10-21 11:44:22 EDT
This is because RemoveCOmmand keep reference to list

testcase to reproduce it.
    Order order1 = getModel1Factory().createOrder();
    OrderDetail orderDetail = getModel1Factory().createOrderDetail();

    order1.getOrderDetails().add(orderDetail);
    resource.getContents().add(order1);
    EList<OrderDetail> list = order1.getOrderDetails();
    resource.getContents().remove(0); // remove object by index
    // EXCEPTION
    list.remove(orderDetail);
    transaction.commit();
Comment 5 Simon Mc Duff CLA 2008-10-21 19:37:35 EDT
Created attachment 115764 [details]
Patch v1

Vic,

can you try this!!
Comment 6 Victor Roldan Betancort CLA 2008-10-22 06:25:36 EDT
Hi Simon,

thanks for this fast patching!
The problem is solved for the case I exposed, but seems to persist in some other more complex cases. I'll try to reproduce it and let you know!
Comment 7 Simon Mc Duff CLA 2008-10-22 07:45:12 EDT
You mean you still have a NPE somewhere.

Humm.. this is strange. CAn you post the stack trace of the problem to see if it is the same ?

With which Command do you still have problem ? RemoveCommand ?


Simon
Comment 8 Victor Roldan Betancort CLA 2008-10-22 07:59:32 EDT
(In reply to comment #7)
> You mean you still have a NPE somewhere.
> Humm.. this is strange. CAn you post the stack trace of the problem to see if
> it is the same ?
> With which Command do you still have problem ? RemoveCommand ?

yes, still the same, but now the deletion is more complicated: I'm removing, like before, a parent and its child, but I'm also now removing the child of another parent now.


A - B
|   |
|   C
|
* - D
    |
    E

I select to remove E, D and C (A and B and left unselected for the removal).
It causes an efect similar as the first test I provided.
C references E.

Haven't tried thoroughly, so I cannot assure what's going on. I'm a bit busy with something else now, but I'll investigate and let you know ASAP.

Regards,
ViK.
Comment 9 Simon Mc Duff CLA 2008-10-22 09:13:40 EDT
It is very strange that you still have the NullPointerException.. because CDOStoreEList doesn't exist anymore.

WHen you have the chance.. please do put the stack trace ?
Comment 10 Victor Roldan Betancort CLA 2008-10-22 09:43:22 EDT
Simon,

Is EMF 2.5 necessary for this patch?

I'm using 2.4.1.
Comment 11 Simon Mc Duff CLA 2008-10-22 09:51:40 EDT
(In reply to comment #10)
> Simon,
> 
> Is EMF 2.5 necessary for this patch?
> 
> I'm using 2.4.1.
> 

Humm.. I used 2.5 I'm not sure if we absolutely need 2.5. In the close future yes...

With the stack trace I think I can have an  idea of the problem since it cannot be the same stack trace as before.

Simon
Comment 12 Victor Roldan Betancort CLA 2008-10-22 10:45:24 EDT
Simon,

sorry for the delay, been a it busy preparing a dedicated CDO server machine.

> With the stack trace I think I can have an  idea of the problem since it cannot be the same stack trace as before.

Yes, you are right.

The error happens in DeleteCommand again, when executing at doExecute()

for (i = indices.length - 1; i >= 0; i--)
{
  ownerList.remove(indices[i]);
}

The StackTrace:

org.eclipse.emf.cdo.util.ObjectNotFoundException: Object OID12587 not found (temporary = false).
	at org.eclipse.emf.internal.cdo.util.FSMUtil.validate(FSMUtil.java:185)
	at org.eclipse.emf.internal.cdo.CDOTransactionImpl.getObject(CDOTransactionImpl.java:421)
	at org.eclipse.emf.internal.cdo.CDOViewImpl.convertIDToObject(CDOViewImpl.java:926)
	at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:180)
	at org.eclipse.emf.internal.cdo.CDOObjectImpl.depopulateRevisionFeature(CDOObjectImpl.java:416)
	at org.eclipse.emf.internal.cdo.CDOObjectImpl.cdoInternalPostDetach(CDOObjectImpl.java:380)
	at org.eclipse.emf.internal.cdo.CDOStateMachine.detach(CDOStateMachine.java:236)
	at org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl.detached(CDOResourceImpl.java:766)
	at org.eclipse.emf.internal.cdo.CDOObjectImpl.eBasicSetContainer(CDOObjectImpl.java:807)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eInverseRemove(BasicEObjectImpl.java:1438)
	at org.eclipse.emf.ecore.util.DelegatingEcoreEList.inverseRemove(DelegatingEcoreEList.java:434)
	at org.eclipse.emf.common.notify.impl.DelegatingNotifyingListImpl.remove(DelegatingNotifyingListImpl.java:701)
	at org.eclipse.emf.edit.command.RemoveCommand.doExecute(RemoveCommand.java:327)
	at org.eclipse.emf.edit.command.AbstractOverrideableCommand.execute(AbstractOverrideableCommand.java:131)
	at org.eclipse.emf.common.command.CompoundCommand.execute(CompoundCommand.java:267)
	at org.eclipse.emf.common.command.CompoundCommand.execute(CompoundCommand.java:267)
	at org.eclipse.emf.edit.command.DeleteCommand.execute(DeleteCommand.java:136)
	at org.eclipse.emf.common.command.BasicCommandStack.execute(BasicCommandStack.java:84)
	at org.eclipse.emf.edit.ui.action.CommandActionHandler.run(CommandActionHandler.java:92)
	at org.eclipse.ui.actions.BaseSelectionListenerAction.runWithEvent(BaseSelectionListenerAction.java:168)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:583)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:500)
	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3823)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3422)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2382)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2346)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2198)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:493)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:488)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193)
	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:386)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	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:549)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1236)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1212)
Comment 13 Victor Roldan Betancort CLA 2008-10-22 10:48:15 EDT
I don't know if it helps, but, according to this:

A - B
|   |
|   C
|
* - D
    |
    E


The object that caused the exception would be object "C".
I'll keep searching a little more after luch :)
Comment 14 Simon Mc Duff CLA 2008-10-22 11:06:57 EDT
(In reply to comment #13)
> I don't know if it helps, but, according to this:
> 
> A - B
> |   |
> |   C
> |
> * - D
>     |
>     E
> 
> 
> The object that caused the exception would be object "C".
> I'll keep searching a little more after luch :)
> 

Victor can you tell me which objects you are deleting ? and the order ? (Is it only C?)

Also can you describe each relations

A-B containment = ? , one-to-many ?
A-D containment = ? , one-to-many ?
D-E containment = ? , one-to-many ?
B-C containment = ? , one-to-many ?

Is A the resource ? Otherwise where it is ?

It is when we detach "C" we have the exception or is it the object not found is C ?
In the case where we have the exception when C is detached I would like to know to which object C is referring.

Thank you!



Comment 15 Simon Mc Duff CLA 2008-10-22 11:32:41 EDT
I think it is a real dangling reference since the objects you try to access was already removed.

But I think we should revisit the fact that an object isn't available when we remove it.

I think until we commit the detached object should be available until we commit.
Obvisouly you have case that objects still need to be accessible.

What do you think ?
Comment 16 Simon Mc Duff CLA 2008-10-22 11:41:19 EDT
Created attachment 115825 [details]
Patch v2 - with no testcase updated

Vic test it.

Detach object are still available until we commit.
Comment 17 Victor Roldan Betancort CLA 2008-10-22 11:50:43 EDT
Yay, It works!!!

I think keeping detached objects should fix many other issues in GMF :)

Thank you!
Comment 18 Simon Mc Duff CLA 2008-10-22 12:11:38 EDT
Created attachment 115828 [details]
Patch v3 - Final

Detached objects are still available except for object with state = NEW.
Comment 19 Simon Mc Duff CLA 2008-10-22 16:49:55 EDT
Maybe objects should be available only internally, not through the public API ...
CDOView.getObject
What do you think Eike ?
Comment 20 Eike Stepper CLA 2008-10-27 03:16:30 EDT
Created attachment 116162 [details]
Patch v4 - ready to be committed

Simon, I'm not sure about the question in your last comment...
Comment 21 Simon Mc Duff CLA 2008-10-27 09:31:27 EDT
Committed to HEAD
Comment 22 Eike Stepper CLA 2008-11-04 17:02:26 EST
Fix available in CDO 2.0.0 I200811041537
Comment 23 Eike Stepper CLA 2009-06-27 11:48:31 EDT
Generally available.