Bug 162779 - NullPointerException in UpdateManager.firePainting(Rectangle)
Summary: NullPointerException in UpdateManager.firePainting(Rectangle)
Status: RESOLVED FIXED
Alias: None
Product: GEF
Classification: Tools
Component: GEF-Legacy Draw2d (show other bugs)
Version: 3.2.1   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: 3.4.0 (Ganymede) RC2   Edit
Assignee: Anthony Hunter CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2006-10-30 13:34 EST by Del Myers CLA
Modified: 2008-09-18 13:48 EDT (History)
2 users (show)

See Also:


Attachments
proposed patch (675 bytes, patch)
2006-10-30 13:50 EST, Del Myers CLA
ahunter.eclipse: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Del Myers CLA 2006-10-30 13:34:01 EST
I have an editpart viewer that listens for paint events in other editpart viewers. So, my viewer adds and removes paint listeners from update managers quite often. As a result, I believe that I found this bug in the UpdateManager code. I think that it originates in the removeUpdateListener(UpdateListener) source:


public void removeUpdateListener(UpdateListener listener) {
	if (listener == null)
		throw new IllegalArgumentException();
	for (int index = 0; index < listeners.length; index++)
		if (listeners[index] == listener) {
			int newSize = listeners.length - 1;
/****** BUG Here: newListeners[] is set to null when the new size==0 *****/
			UpdateListener newListeners[] = null;
/*************************************************************************/
			if (newSize != 0) {
				newListeners = new UpdateListener[newSize];
				System.arraycopy(listeners, 0, newListeners, 0, index);
				System.arraycopy(listeners, index + 1, newListeners, index, newSize - index);
			}
/*************** BUG here newListeners is null when newSize == 0 ************/
			listeners = newListeners;
/***************************************************************************/
			return;
		}
}

Then firePainting(Rectangle, Map) assumes that this.listeners will never be null:

protected void firePainting(Rectangle damage, Map dirtyRegions) {
	UpdateListener localListeners[] = listeners;
	for (int i = 0; i < localListeners.length; i++)
		localListeners[i].notifyPainting(damage, dirtyRegions);
}


The bug, I believe, can be fixed by either setting the listeners to a size-0 array, or by checking for null.

Here is my stack trace:



3-0\13-0\13-2\00-193-1\03-0\12-0\1org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.NullPointerException)
	at org.eclipse.swt.SWT.error(SWT.java:3374)
	at org.eclipse.swt.SWT.error(SWT.java:3297)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:126)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3325)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2971)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1914)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1878)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at zestrcp.Application.run(Application.java:18)
	at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
	at org.eclipse.core.launcher.Main.run(Main.java:977)
	at org.eclipse.core.launcher.Main.main(Main.java:952)
Caused by: java.lang.NullPointerException
	at org.eclipse.draw2d.UpdateManager.firePainting(UpdateManager.java:113)
	at org.eclipse.draw2d.DeferredUpdateManager.repairDamage(DeferredUpdateManager.java:267)
	at org.eclipse.draw2d.DeferredUpdateManager.performUpdate(DeferredUpdateManager.java:167)
	at org.eclipse.draw2d.DeferredUpdateManager$UpdateRequest.run(DeferredUpdateManager.java:46)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:123)
	... 20 more
Comment 1 Del Myers CLA 2006-10-30 13:50:38 EST
Created attachment 52951 [details]
proposed patch

adds an "else" check in removeUpdateListener(UpdateListener) for when the new size is 0. If so, a size-0 UpdateListener array is created.
Comment 2 Anthony Hunter CLA 2008-05-26 13:46:02 EDT
Committed the fix to HEAD.
Comment 3 Anthony Hunter CLA 2008-05-26 13:46:19 EDT
Committed the fix to HEAD.