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

Bug 404312

Summary: NPE in HandledContributionItem.canExecuteItem()
Product: [Eclipse Project] Platform Reporter: Marc Gobeil <mgobeil>
Component: UIAssignee: Paul Webster <pwebster>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3 CC: daniel_megert, eclipse, elaskavaia.cdt, olejorgenb, pelder.eclipse, pwebster, stepper, tom.schindl
Version: 4.2.2   
Target Milestone: 4.4 M1   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Bug Depends on:    
Bug Blocks: 411054, 411057, 413535    
Attachments:
Description Flags
Patch for 4.2 maintenance branch none

Description Marc Gobeil CLA 2013-03-25 16:39:38 EDT
The javadoc for HandledContributionItem.getContext() states that it should return "the closest context, or global context if none in the hierarchy", but when it its getContextForParent() method delegates to ModelServiceImpl.getContainingContext(), which delegates to ModelUtils.getContainingContext(), it simply returns null when it can't find one in the hierarchy.  This causes an NPE in HandledContributionItem.canExecuteItem(), which assumes a non-null context.  

See stack trace below:

Thread [main] (Suspended (breakpoint at line 194 in ModelUtils))	
	ModelUtils.getContainingContext(MApplicationElement) line: 194	
	ModelServiceImpl.getContainingContext(MUIElement) line: 276	
	HandledContributionItem.getContextForParent(MUIElement) line: 852	
	HandledContributionItem.getContext(MUIElement) line: 866	
	HandledContributionItem.canExecuteItem(Event) line: 822	
	HandledContributionItem.access$2(HandledContributionItem, Event) line: 817	
	HandledContributionItem$3.run() line: 216	
	SafeRunner.run(ISafeRunnable) line: 42	
	HandledContributionItem.updateItemEnablement() line: 243	
	HandledContributionItem$ToolItemUpdateTimer.run() line: 146	
	Display.runTimer(int) line: 4270	
	Display.messageProc(int, int, int, int) line: 3357	
	OS.DispatchMessageW(MSG) line: not available [native method]	
	OS.DispatchMessage(MSG) line: 2546	
	Display.readAndDispatch() line: 3756	
	PartRenderingEngine$9.run() line: 1029	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 923	
	E4Workbench.createAndRunUI(MApplicationElement) line: 86	
	Workbench$5.run() line: 588	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 543	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	IDEApplication.start(IApplicationContext) line: 124	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 353	
	EclipseStarter.run(String[], Runnable) line: 180	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available	
	Method.invoke(Object, Object...) line: not available	
	Main.invokeFramework(String[], URL[]) line: 629	
	Main.basicRun(String[]) line: 584	
	Main.run(String[]) line: 1438	
	Main.main(String[]) line: 1414
Comment 1 Paul Webster CLA 2013-03-25 16:59:05 EDT
We can add an NPE guard, but the real question is what's wrong with the model that a rendered item is not contained within a rendered element with a context?

PW
Comment 2 Marc Gobeil CLA 2013-03-25 17:07:14 EDT
We're messing around with a custom toolbar, and trying to override standard handling of the normal toolbars, so it's likely we've accidentally violated that rule in the process.  An NPE guard with a log message that gave the explanation you just did would be helpful though :)
Comment 3 Elena Laskavaia CLA 2013-05-31 13:35:28 EDT
I think we found a problem. NPE is just side effect of platform removing
random toolbar items ny cool bar manager

This is code:

CoolBarToTrimManager:
	public IContributionItem remove(IContributionItem item) {
		final List<MToolBar> children = modelService.findElements(window, null, MToolBar.class, null);
                /// ^^^ here we getting childen, forming list A
		for (int i = 0; i < children.size(); i++) {
			final MToolBar child = children.get(i);
			final Object obj = child.getTransientData().get(OBJECT);
			if (obj != null && obj.equals(item)) {
                                // we found our child with index i
				...
				workbenchTrimElements.remove(child);

				child.setToBeRendered(false);
                                // we removing now element i from list B
                                // list A != list B!!!!!
                                // random element is removed
				child.getParent().getChildren().remove(i);
				return (IContributionItem) obj;
			}
                        ...
		}
		return null;
	}
Comment 4 Elena Laskavaia CLA 2013-05-31 13:39:59 EDT
Created attachment 231829 [details]
Patch for 4.2 maintenance branch
Comment 5 Marc Gobeil CLA 2013-05-31 13:58:17 EDT
Also:
- the hack applied by Bug 388516 was probably trying to mask this out, and can probably be removed after this is fixed
- even when this went wrong, the exception shouldn't have repeated indefinitely

For the second point, the runnable container that the hack code introduced in 388516 was embedded in, schedules itself every 400ms "until the list goes empty".  As we've seen here, this is dangerous because HandledContributionItem.updateItemEnablement() runs code in a SafeRunner that suppresses any exceptions thrown, but even when operating without throwing an exception, that polling loop can easily become a hidden performance problem.
Comment 6 Paul Webster CLA 2013-05-31 16:04:31 EDT
Once we put this in master and 4.3.1 we can consider patching it back to R4_2_maintenance

PW
Comment 7 Elena Laskavaia CLA 2013-06-05 13:24:06 EDT
Any progress on applying this to master at least?
Comment 8 Paul Webster CLA 2013-06-05 13:35:32 EDT
We're in Kepler RC4, in effect no changes but doc changes.  I'm not sure when Luna and 4.3.1 will be open again, but some time possibly in the next 3 weeks.

PW
Comment 9 Paul Webster CLA 2013-06-17 10:58:22 EDT
*** Bug 410712 has been marked as a duplicate of this bug. ***
Comment 11 Elena Laskavaia CLA 2013-06-19 11:04:37 EDT
Do I need to clone it to get into maintanance branch?
Comment 12 Paul Webster CLA 2013-06-19 12:35:13 EDT
(In reply to comment #11)
> Do I need to clone it to get into maintanance branch?

I've already cloned a bug so it can be backported once 4.3.1 opens

PW
Comment 13 Paul Webster CLA 2013-07-29 15:39:13 EDT
(In reply to comment #11)
> Do I need to clone it to get into maintanance branch?

Elena, Could you please sign your CLA - http://wiki.eclipse.org/CLA

PW
Comment 14 Paul Webster CLA 2013-08-01 15:19:38 EDT
(In reply to comment #13)
> 
> Elena, Could you please sign your CLA - http://wiki.eclipse.org/CLA

Hi Elena,

I'd like to get this into 4.3.1 but the window is short.  Did you get a chance to look at the CLA?

PW
Comment 15 Elena Laskavaia CLA 2013-08-01 16:35:06 EDT
(In reply to comment #14)

> > 
> > Elena, Could you please sign your CLA - http://wiki.eclipse.org/CLA
> 
Signed
Comment 17 Paul Webster CLA 2013-08-07 13:26:33 EDT
In 4.4.0.I20130806-2000

PW
Comment 18 Dani Megert CLA 2013-08-09 06:14:59 EDT
(In reply to comment #16)
> Release on 4.3 maintenance as:
> 
> https://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/
> ?h=R4_3_maintenance&id=03ef555d031fbf1c342116f8c281e174ff30da63

This is covered by bug 411054.