Project: Eclipse_Platform_UI
Bug 118674 [DataBinding] Deleting an object from a viewer causes null object assertion
Reported: 2005-11-30 12:54:48 | Status: verified fixed

An unexpected error has occurred in the application. You may be able to continue working with reduced functionality. Version: 1.0.1 org.eclipse.jface.util.Assert$AssertionFailedException: null argument; org.eclipse.jface.util.Assert.isNotNull(Assert.java:149) org.eclipse.jface.util.Assert.isNotNull(Assert.java:125) org.eclipse.jface.viewers.StructuredViewer.assertElementsNotNull(StructuredViewer.java:545) org.eclipse.jface.viewers.StructuredViewer.getRawChildren(StructuredViewer.java:849) org.eclipse.jface.viewers.TableViewer.getRawChildren(TableViewer.java:1086) org.eclipse.jface.viewers.StructuredViewer.getFilteredChildren(StructuredViewer.java:790) org.eclipse.jface.viewers.StructuredViewer.getSortedChildren(StructuredViewer.java:905) org.eclipse.jface.viewers.TableViewer.internalRefreshAll(TableViewer.java:798) org.eclipse.jface.viewers.TableViewer.internalRefresh(TableViewer.java:748) org.eclipse.jface.viewers.TableViewer.internalRefresh(TableViewer.java:737) org.eclipse.jface.viewers.StructuredViewer$7.run(StructuredViewer.java:1264) org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1201) org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1262) org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1221) org.eclipse.jface.databinding.internal.viewers.TableViewerUpdatableCollection.internalAddElement(TableViewerUpdatableCollection.java:75) org.eclipse.jface.databinding.internal.viewers.TableViewerUpdatableCollection.access$1(TableViewerUpdatableCollection.java:70) org.eclipse.jface.databinding.internal.viewers.TableViewerUpdatableCollection$4.run(TableViewerUpdatableCollection.java:115) org.eclipse.jface.databinding.internal.swt.AsyncRunnable.runOn(AsyncRunnable.java:26) org.eclipse.jface.databinding.internal.viewers.TableViewerUpdatableCollection.setElement(TableViewerUpdatableCollection.java:119) org.eclipse.jface.databinding.internal.CollectionBinding.update(CollectionBinding.java:123) org.eclipse.jface.databinding.internal.CollectionBinding.handleChange(CollectionBinding.java:95) org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:61) org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:48) org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:44) org.eclipse.jface.databinding.internal.NestedUpdatableCollection.access$1(NestedUpdatableCollection.java:1) org.eclipse.jface.databinding.internal.NestedUpdatableCollection$1.handleChange(NestedUpdatableCollection.java:35) org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:61) org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:48) org.eclipse.jface.databinding.internal.beans.JavaBeanUpdatableCollection.access$6(JavaBeanUpdatableCollection.java:1) org.eclipse.jface.databinding.internal.beans.JavaBeanUpdatableCollection$1.propertyChange(JavaBeanUpdatableCollection.java:48) java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source) java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source) com.tpc.ipartner.model.ModelObject.firePropertyChange(ModelObject.java:46) com.tpc.ipartner.model.ShowPerson.removeGiftCertificate(ShowPerson.java:819) com.tpc.ipartner.show.editors.pages.customer.tabs.giftcertificate.GiftCertificateTableRemoveHandler.removeObject(GiftCertificateTableRemoveHandler.java:20) com.tpc.custom.controls.table.AbstractRemoveButtonHandler.mouseClickProceed(AbstractRemoveButtonHandler.java:33) com.tpc.custom.controls.table.AbstractButtonHandler.mouseClick(AbstractButtonHandler.java:86) com.tpc.custom.controls.table.AbstractButtonHandler.mouseUp(AbstractButtonHandler.java:79) org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:137) org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:843) org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3080) org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2713) org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1699) org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1663) org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:367) org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143) com.tpc.ipartner.BaseApplication.run(BaseApplication.java:31) org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163) 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.core.launcher.Main.invokeFramework(Main.java:334) org.eclipse.core.launcher.Main.basicRun(Main.java:278) org.eclipse.core.launcher.Main.run(Main.java:973) org.eclipse.core.launcher.Main.main(Main.java:948) The problem appears to be at: org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:44) Here is a patch that fixes the problem: Index: Updatable.java =================================================================== RCS file: /home/eclipse/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/Updatable.java,v retrieving revision 1.5 diff -u -r1.5 Updatable.java --- Updatable.java 19 Nov 2005 05:06:36 -0000 1.5 +++ Updatable.java 30 Nov 2005 17:16:29 -0000 @@ -41,7 +41,7 @@ protected ChangeEvent fireChangeEvent(int changeType, Object oldValue, Object newValue) { - return fireChangeEvent(changeType, oldValue, newValue, 0); + return fireChangeEvent(changeType, oldValue, newValue, -1); // FIXME: djo We came from a collection delete event; we don't know the position } protected ChangeEvent fireChangeEvent(int changeType, Object oldValue, Object newValue, int position) { The problem is that the old code passes 0 as the position parameter, but TableViewerUpdatableCollection expects -1 for the position parameter to mean that "we don't know the position". Changing the code as shown in the above patch causes TableViewerUpdatableCollection to work properly, but causes a unit test failure as follows: There was 1 failure: 1) testFireChangeEvent(org.eclipse.jface.tests.databinding.UpdatableTest)junit.framework.AssertionFailedError: unexpected method call: handleChange at org.eclipse.jface.tests.databinding.util.Mocks$MockInvocationHandler.invoke(Mocks.java:137) at org.eclipse.jface.tests.databinding.util.$Proxy0.handleChange(Unknown Source) at org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:61) at org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:48) at org.eclipse.jface.databinding.Updatable.fireChangeEvent(Updatable.java:44) at org.eclipse.jface.tests.databinding.UpdatableTest$MyUpdatable.fireChange(UpdatableTest.java:27) at org.eclipse.jface.tests.databinding.UpdatableTest.testFireChangeEvent(UpdatableTest.java:137) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at org.eclipse.jface.tests.databinding.BindingTestSuite.main(BindingTestSuite.java:21) I'm not sure if my fix is the correct fix since it causes a failure in exactly the unit test that I would expect to be failing due to this bug. Boris or Joe: Please review and advise.

Files changed in fix:
bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/ChangeEvent.java bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/Updatable.java bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/internal/NestedUpdatableCollection.java tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/databinding/UpdatableTest.java