Search code examples
javaswteclipse-rcpe4

Debugging a `Widget is disposed` exception


A widget is disposed exception get thrown in our application and I'm struggling to find widget is causing the problem.

It is an RCP 4 application with multiple perspectives and views. When the exception occurs the stack trace shows the last piece of code to be called but doesn't tell us which widget has been disposed of.

I've tried putting breakpoints on the dispose method of Widget but there are so many widgets getting disposed that it is prohibitive.

!ENTRY org.eclipse.e4.ui.workbench 4 0 2019-04-26 10:14:00.114
!MESSAGE Internal Error
!STACK 0
org.eclipse.swt.SWTException: Widget is disposed
    at org.eclipse.swt.SWT.error(SWT.java:4595)
    at org.eclipse.swt.SWT.error(SWT.java:4510)
    at org.eclipse.swt.SWT.error(SWT.java:4481)
    at org.eclipse.swt.widgets.Widget.error(Widget.java:451)
    at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:350)
    at org.eclipse.swt.widgets.Control.computeSize(Control.java:663)
    at org.eclipse.swt.custom.ScrolledCompositeLayout.computeSize(ScrolledCompositeLayout.java:36)
    at org.eclipse.swt.widgets.Composite.computeSizeInPixels(Composite.java:218)
    at org.eclipse.swt.widgets.Control.computeSize(Control.java:666)
    at org.eclipse.swt.layout.GridData.computeSize(GridData.java:494)
    at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:224)
    at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:200)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1362)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1369)
    at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1347)
    at org.eclipse.swt.widgets.Composite.setLayoutDeferred(Composite.java:1148)
    at org.eclipse.swt.widgets.Display.runDeferredLayouts(Display.java:3968)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3540)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1173)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1062)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156)
    at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:166)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:595)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1501)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1474)

What is the best method for finding the cause of a widget is disposed exception?


Solution

  • This turned out to be to do with the ScrolledComposite as @greg-449 mentioned. I missed it when first looking.

    We used the parent composite to create the ScrolledComposite and then set the content. The content was being disposed but the reference was still stored causing the widget is disposed exception.

    final ScrolledComposite scroll = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.BORDER);
    scroll.setContent(widgetThatIsDisposedLater);
    

    To fix this I disposed the ScrolledComposite which meant that it would no longer try using its disposed content.