Community
Participate
Working Groups
Build Identifier: Eclipse 3.5.2, M20100211-1343 GEF 3.6 build I201004252051 (Originally posted in Bug #195527) I'm getting an error exception with this new strategy. I have three figures - one on it's own, and one inside another (parent) figure. The child figure inside the parent has a connection to the one on it's own. When I delete the parent figure (but not the connection) I get this: !ENTRY org.eclipse.ui 4 0 2010-05-12 15:30:26.059 !MESSAGE Unhandled event loop exception !STACK 0 org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.IndexOutOfBoundsException: Index: 3, Size: 3) at org.eclipse.swt.SWT.error(SWT.java:3884) at org.eclipse.swt.SWT.error(SWT.java:3799) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:137) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3885) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3506) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at uk.ac.bolton.archimate.editor.Application.start(Application.java:62) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194) 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:368) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514) at org.eclipse.equinox.launcher.Main.run(Main.java:1311) at org.eclipse.equinox.launcher.Main.main(Main.java:1287) Caused by: java.lang.IndexOutOfBoundsException: Index: 3, Size: 3 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.get(ArrayList.java:322) at org.eclipse.draw2d.FigureUtilities.findCommonAncestor(FigureUtilities.java:369) at org.eclipse.draw2d.ViewportUtilities.getNearestCommonViewport(ViewportUtilities.java:137) at org.eclipse.draw2d.ConnectionLayer$ConnectionLayerClippingStrategy.getEdgeClippingRectangle(ConnectionLayer.java:91) at org.eclipse.draw2d.ConnectionLayer$ConnectionLayerClippingStrategy.getClip(ConnectionLayer.java:55) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1099) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1136) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.ConnectionLayer.paint(ConnectionLayer.java:277) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1103) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1136) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1103) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1136) at org.eclipse.draw2d.ScalableFreeformLayeredPane.paintClientArea(ScalableFreeformLayeredPane.java:61) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1103) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1136) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1103) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1131) at org.eclipse.draw2d.Viewport.paintClientArea(Viewport.java:156) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1103) at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1136) at org.eclipse.draw2d.Figure.paint(Figure.java:1065) at org.eclipse.draw2d.DeferredUpdateManager.paint(DeferredUpdateManager.java:155) at org.eclipse.draw2d.LightweightSystem.paint(LightweightSystem.java:199) at org.eclipse.draw2d.LightweightSystem$2.handleEvent(LightweightSystem.java:107) 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.Widget.sendEvent(Widget.java:1027) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1012) at org.eclipse.swt.widgets.Composite.WM_PAINT(Composite.java:1324) at org.eclipse.swt.widgets.Control.windowProc(Control.java:4001) at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:342) at org.eclipse.swt.widgets.Display.windowProc(Display.java:4632) at org.eclipse.swt.internal.win32.OS.RedrawWindow(Native Method) at org.eclipse.swt.widgets.Control.update(Control.java:3810) at org.eclipse.swt.widgets.Control.update(Control.java:3800) at org.eclipse.draw2d.NativeGraphicsSource.getGraphics(NativeGraphicsSource.java:43) at org.eclipse.draw2d.DeferredUpdateManager.getGraphics(DeferredUpdateManager.java:138) at org.eclipse.draw2d.DeferredUpdateManager.repairDamage(DeferredUpdateManager.java:292) at org.eclipse.draw2d.DeferredUpdateManager.performUpdate(DeferredUpdateManager.java:181) at org.eclipse.draw2d.DeferredUpdateManager$UpdateRequest.run(DeferredUpdateManager.java:48) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134) This does not happen in GEF 3.5.2. Reproducible: Always
It happens as a side-effect of not removing the connections from the deleted object. In 3.5.2 the orphaned connection(s) would remain on the diagram, but in 3.6 there is this exception. You could argue that you when you run a Delete command you should also remove any connections from the model. This is true, but at least in 3.5.2 it acted gracefully. To reproduce in Logic example: 1. In DeleteCommand.java comment out the code in methods deleteConnections(LogicSubpart part). 2. Create a new Logic diagram and add a FullAdder and a Circuit. 3. Make a connection from an inner figure in the FullAdder to a point on the Circuit. 4. Delete the inner figure's parent.
The cause for this actually is that FigureUtilities#findCommonAncestor is not robust against calls with an orphaned figure. The following test case may be used to reproduce the issue: public void test_findCommonAncestor_bugzilla312886() { IFigure orphanFigure = new Figure(); IFigure figureParent = new Figure(); IFigure figureChild = new Figure(); figureParent.add(figureChild); assertNull(FigureUtilities .findCommonAncestor(figureChild, orphanFigure)); } It will deliver the following result: IndexOutOfBoundsException: Index : 2, Size:2
- Fixed javadoc of FigureUtilities#findCommonAncestor() stated that the method would return null in case one figure is the ancestor of the other (the changes made as part of bug#130042 and the test case belonging to this demonstrated that other behavior was expected). - Reimplemented FigureUtilities#findCommonAncestor() to correctly handle orphaned children, which was broken. - Made ViewportUtilities#findNearestViewport() and ViewportUtilities#findNearestEnclosingViewport() robust against null arguments. - Added additional test cases to FigureUtilitiesTest. Committed changes to 3.6 maintenance branch and cvs HEAD (3.7). Marking as resolved in 3.6.2.