Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 334580

Summary: View tool bar is disposed prematurely even though it's still up in another perspective
Product: [Eclipse Project] e4 Reporter: Remy Suen <remy.suen>
Component: UIAssignee: Remy Suen <remy.suen>
Status: VERIFIED FIXED QA Contact: Eric Moffatt <emoffatt>
Severity: normal    
Priority: P3 CC: Olivier_Thomann, pwebster
Version: 1.0   
Target Milestone: 4.1 M7   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
ToolBar rendering patch v1
none
ToolBar rendering patch v2
none
ToolBar rendering patch v3
none
ToolBar rendering patch v3 none

Description Remy Suen CLA 2011-01-17 15:25:48 EST
I somehow got into a state where clicking the dropdown for the 'JUnit' view's history would just keep throwing NPEs. Closing all instances of the view in all perspectives and reopening the view resolved the problem.

java.lang.NullPointerException
	at org.eclipse.jdt.internal.ui.viewsupport.HistoryDropDownAction$1.menuAboutToShow(HistoryDropDownAction.java:73)
	at org.eclipse.jface.action.MenuManager.fireAboutToShow(MenuManager.java:338)
	at org.eclipse.jface.action.MenuManager.handleAboutToShow(MenuManager.java:469)
	at org.eclipse.jface.action.MenuManager.access$1(MenuManager.java:465)
	at org.eclipse.jface.action.MenuManager$2.menuShown(MenuManager.java:491)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:245)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1058)
	at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:4643)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:4332)
	at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
	at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1610)
	at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2061)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4896)
	at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method)
	at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:256)
	at org.eclipse.swt.widgets.Display.runPopups(Display.java:4130)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3674)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$6.run(PartRenderingEngine.java:810)
Comment 1 Remy Suen CLA 2011-01-18 13:51:34 EST
1. Ctrl+3 > JUnit
2. Click the history dropdown once to force it to be created and shown.
3. Window > Open Perspective > Debug
4. Ctrl+3 > JUnit
5. Window > Open Perspective > Java
6. Window > Reset Perspective... > Yes
7. Ctrl+3 > JUnit
8. Click the dropdown again. The NPE will be thrown.
Comment 2 Remy Suen CLA 2011-01-18 13:59:36 EST
The tool item shouldn't have been destroyed when the perspective was reset since the view itself was still open in the 'Debug' perspective.

Thread [main] (Suspended (breakpoint at line 133 in HistoryDropDownAction$HistoryMenuCreator))	
	HistoryDropDownAction$HistoryMenuCreator.dispose() line: 133	
	ActionContributionItem.handleWidgetDispose(Event) line: 474	
	ActionContributionItem.access$1(ActionContributionItem, Event) line: 466	
	ActionContributionItem$6.handleEvent(Event) line: 447	
	EventTable.sendEvent(Event) line: 84	
	ToolItem(Widget).sendEvent(Event) line: 1053	
	ToolItem(Widget).sendEvent(int, Event, boolean) line: 1077	
	ToolItem(Widget).sendEvent(int) line: 1058	
	ToolItem(Widget).release(boolean) line: 808	
	ToolBar.releaseChildren(boolean) line: 807	
	ToolBar(Widget).release(boolean) line: 811	
	CTabFolder(Composite).releaseChildren(boolean) line: 873	
	CTabFolder(Widget).release(boolean) line: 811	
	CTabFolder(Widget).dispose() line: 446	
	StackRenderer(SWTPartRenderer).disposeWidget(MUIElement) line: 137	
	PartRenderingEngine.safeRemoveGui(MUIElement) line: 664	
	PartRenderingEngine.access$1(PartRenderingEngine, MUIElement) line: 615	
	PartRenderingEngine$5.run() line: 610	
	SafeRunner.run(ISafeRunnable) line: 42	
	PartRenderingEngine.removeGui(MUIElement) line: 595	
	PartRenderingEngine.safeRemoveGui(MUIElement) line: 648	
	PartRenderingEngine.access$1(PartRenderingEngine, MUIElement) line: 615	
	PartRenderingEngine$5.run() line: 610	
	SafeRunner.run(ISafeRunnable) line: 42	
	PartRenderingEngine.removeGui(MUIElement) line: 595	
	PartRenderingEngine$1.handleEvent(Event) line: 136	
	UIEventHandler.handleEvent(Event) line: 41	
	EventHandlerWrapper.handleEvent(Event, Permission) line: 197	
	EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event) line: 197	
	EventHandlerTracker.dispatchEvent(Object, Object, int, Object) line: 1	
	EventManager.dispatchEvent(Set<Entry<K,V>>, EventDispatcher<K,V,E>, int, E) line: 230	
	ListenerQueue<K,V,E>.dispatchEventSynchronous(int, E) line: 148	
	EventAdminImpl.dispatchEvent(Event, boolean) line: 135	
	EventAdminImpl.sendEvent(Event) line: 78	
	EventComponent.sendEvent(Event) line: 39	
	EventBroker.send(String, Object) line: 73	
	UIEventPublisher.notifyChanged(Notification) line: 58	
	PartSashContainerImpl(BasicNotifierImpl).eNotify(Notification) line: 380	
	PartSashContainerImpl(UIElementImpl).setToBeRendered(boolean) line: 288	
	WorkbenchPage.resetPerspective() line: 2543

Alternate steps to reproduce the problem:
1. Ctrl+3 > JUnit
2. Click the history dropdown once to force it to be created and shown.
3. Window > Open Perspective > Debug
4. Ctrl+3 > JUnit
5. Window > Open Perspective > Java
6. Close the 'JUnit' view.
7. Close the 'Package Explorer' view.
8. Ctrl+3 > JUnit
9. Click the dropdown again. The NPE will be thrown.
Comment 3 Remy Suen CLA 2011-03-11 13:32:46 EST
*** Bug 339743 has been marked as a duplicate of this bug. ***
Comment 4 Remy Suen CLA 2011-03-11 13:37:46 EST
(In reply to comment #0)
> I somehow got into a state where clicking the dropdown for the 'JUnit' view's
> history would just keep throwing NPEs. Closing all instances of the view in all
> perspectives and reopening the view resolved the problem.

If this workaround doesn't work, make sure you close all instances of that view in all perspectives as well as "destroying" any stack it was under by closing all of its sibling parts.
Comment 5 Remy Suen CLA 2011-03-11 14:51:52 EST
Created attachment 191024 [details]
ToolBar rendering patch v1

Reparent the control so that it doesn't get disposed when the tab folder is disposed.
Comment 6 Remy Suen CLA 2011-04-06 16:12:39 EDT
Created attachment 192666 [details]
ToolBar rendering patch v2

Arbitrarily reparenting the control will mean it may never get disposed. This new patch changes more code in other areas and tries to keep a consistent state by using the visibility of the element to prevent controls from being disposed randomly.

I don't really like this approach because the renderer's disposeWidget(MUIElement) method is still not actually disposing the widget.
Comment 7 Remy Suen CLA 2011-04-07 09:29:39 EDT
Created attachment 192735 [details]
ToolBar rendering patch v3

This patch is less disruptive and forces all changes to be in the ContributedPartRenderer and StackRenderer instead.

The CPR will handle the disposal of the part's toolbar and menus (not ideal in my opinion but does ensure that they don't go away unless the part goes away). The SR's sole purpose is for toggling the visibility states of the toolbars and will not force the toolbars to be unrendered.
Comment 8 Remy Suen CLA 2011-04-07 09:30:58 EDT
Created attachment 192736 [details]
ToolBar rendering patch v3

It seems I missed the StackRenderer from my patch.
Comment 9 Remy Suen CLA 2011-04-07 11:31:09 EDT
(In reply to comment #8)
> Created attachment 192736 [details]
> ToolBar rendering patch v3

Patch released to CVS HEAD.
Comment 10 Remy Suen CLA 2011-04-26 10:11:59 EDT
Verified with I20110426-0200 on Windows XP.