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

Bug 345600

Summary: [Workbench] NullPointerException at shutdown when a view has a Browser in it
Product: [Eclipse Project] Platform Reporter: Marco Maccaferri <macca>
Component: UIAssignee: Platform-UI-Inbox <Platform-UI-Inbox>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: dylan.mcreynolds, emoffatt, grant_gayed, justin, niklas.deutschmann, ob1.eclipse, pwebster, remy.suen, s.muecke, Silenio_Quarti
Version: 3.6.2   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Marco Maccaferri CLA 2011-05-12 09:32:26 EDT
Build Identifier: M20110210-1200

Sometimes when shutting down our RCP application we get the following exception:

java.lang.NullPointerException
    at org.eclipse.ui.internal.WorkbenchWindow.hardClose(WorkbenchWindow.java:1688)
    at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:734)
    at org.eclipse.ui.internal.WorkbenchWindow.access$0(WorkbenchWindow.java:710)
    at org.eclipse.ui.internal.WorkbenchWindow$5.run(WorkbenchWindow.java:832)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:830)
    at org.eclipse.jface.window.Window.handleShellCloseEvent(Window.java:741)
    at org.eclipse.jface.window.Window$3.shellClosed(Window.java:687)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:98)
    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:1062)
    at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:308)
    at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1665)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:4164)
    at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
    at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1598)
    at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2038)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4873)
    at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
    at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2454)
    at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:497)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:4253)
    at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
    at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1598)
    at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2038)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4873)
    at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
    at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2454)
    at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:497)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:4253)
    at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
    at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1598)
    at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2038)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4873)
    at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
    at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2459)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3655)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at com.rtrms.amoeba.internal.Application.run(Application.java:25)
    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.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
    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:369)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    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.equinox.launcher.Main.invokeFramework(Main.java:620)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1384)


Seems that workbench.getService may return null at this point but the condition is never checked.


Reproducible: Sometimes
Comment 1 Dylan McReynolds CLA 2012-05-07 12:38:50 EDT
I am seeing this same exact stack trace for our RCP application. One thing I can add is that it only happens when closing the application with Alt+F4, never when closing the window through with the Close button. Even then, only when a view with a Browser widget is in focus (this is on Windows 7).
Comment 2 Paul Webster CLA 2012-05-07 12:42:53 EDT
(In reply to comment #1)
> I am seeing this same exact stack trace for our RCP application. One thing I
> can add is that it only happens when closing the application with Alt+F4, never
> when closing the window through with the Close button. Even then, only when a
> view with a Browser widget is in focus (this is on Windows 7).

Is there anything in your RCP app runtime .log file?  or on the console if you don't have a workspace and run with -consoleLog?

PW
Comment 3 Dylan McReynolds CLA 2012-05-07 12:51:42 EDT
I just have the stack trace that the original submitter posted.

Interestingly, I put a breakpoint into WorkbenchWindows.hardClose(). The method is getting called twice. The first time it looks like the Window being closed is my main application window. The exception does not occur. Then, I hit the breakpoint again, but the Window has a null Shell. Perhaps a hidden window? Something specific to the Browser widget on Windows? Still investigating.
Comment 4 Paul Webster CLA 2012-05-07 13:59:36 EDT
(In reply to comment #3)
> I just have the stack trace that the original submitter posted.
> 
> Interestingly, I put a breakpoint into WorkbenchWindows.hardClose(). The method
> is getting called twice. The first time it looks like the Window being closed
> is my main application window. The exception does not occur. Then, I hit the
> breakpoint again, but the Window has a null Shell. Perhaps a hidden window?
> Something specific to the Browser widget on Windows? Still investigating.

Could you attach a stack trace from the debugger for the first (successful) close?

PW
Comment 5 Dylan McReynolds CLA 2012-05-07 14:12:44 EDT
Paul,

Is this what you're looking for? This was done while stopped on the breakpoint, during the first pass (which does not blow up) just at the spot where the second pass gets an NPE with a null handlerService object.

Dylan

Thread [main] (Suspended)	
	WorkbenchWindow.hardClose() line: 1688	
	WorkbenchWindow.busyClose() line: 734	
	WorkbenchWindow.access$0(WorkbenchWindow) line: 710	
	WorkbenchWindow$5.run() line: 832	
	BusyIndicator.showWhile(Display, Runnable) line: 70	
	WorkbenchWindow.close() line: 830	
	WindowManager.close() line: 109	
	Workbench$18.run() line: 1106	
	SafeRunner.run(ISafeRunnable) line: 42	
	Workbench.busyClose(boolean) line: 1103	
	Workbench.access$15(Workbench, boolean) line: 1032	
	Workbench$25.run() line: 1276	
	BusyIndicator.showWhile(Display, Runnable) line: 70	
	Workbench.close(int, boolean) line: 1274	
	Workbench.close() line: 1246	
	WorkbenchWindow.busyClose() line: 731	
	WorkbenchWindow.access$0(WorkbenchWindow) line: 710	
	WorkbenchWindow$5.run() line: 832	
	BusyIndicator.showWhile(Display, Runnable) line: 70	
	WorkbenchWindow.close() line: 830	
	WorkbenchWindow(Window).handleShellCloseEvent() line: 741	
	Window$3.shellClosed(ShellEvent) line: 687	
	TypedListener.handleEvent(Event) line: 98	
	EventTable.sendEvent(Event) line: 84	
	Shell(Widget).sendEvent(Event) line: 1053	
	Shell(Widget).sendEvent(int, Event, boolean) line: 1077	
	Shell(Widget).sendEvent(int, Event) line: 1062	
	Shell(Decorations).closeWidget() line: 308	
	Shell(Decorations).WM_CLOSE(long, long) line: 1665	
	Shell(Control).windowProc(long, int, long, long) line: 4164	
	Shell(Canvas).windowProc(long, int, long, long) line: 341	
	Shell(Decorations).windowProc(long, int, long, long) line: 1598	
	Shell.windowProc(long, int, long, long) line: 2038	
	Display.windowProc(long, long, long, long) line: 4873	
	OS.DefWindowProcW(long, int, long, long) line: not available [native method]	
	OS.DefWindowProc(long, int, long, long) line: 2454	
	Shell.callWindowProc(long, int, long, long) line: 497	
	Shell(Control).windowProc(long, int, long, long) line: 4253	
	Shell(Canvas).windowProc(long, int, long, long) line: 341	
	Shell(Decorations).windowProc(long, int, long, long) line: 1598	
	Shell.windowProc(long, int, long, long) line: 2038	
	Display.windowProc(long, long, long, long) line: 4873	
	OS.DispatchMessageW(MSG) line: not available [native method]	
	OS.DispatchMessage(MSG) line: 2459	
	Display.readAndDispatch() line: 3655	
	WorkbenchWindow.canHandleShellCloseEvent() line: 817	
	Window$3.shellClosed(ShellEvent) line: 686	
	TypedListener.handleEvent(Event) line: 98	
	EventTable.sendEvent(Event) line: 84	
	Shell(Widget).sendEvent(Event) line: 1053	
	Shell(Widget).sendEvent(int, Event, boolean) line: 1077	
	Shell(Widget).sendEvent(int, Event) line: 1062	
	Shell(Decorations).closeWidget() line: 308	
	Shell(Decorations).WM_CLOSE(long, long) line: 1665	
	Shell(Control).windowProc(long, int, long, long) line: 4164	
	Shell(Canvas).windowProc(long, int, long, long) line: 341	
	Shell(Decorations).windowProc(long, int, long, long) line: 1598	
	Shell.windowProc(long, int, long, long) line: 2038	
	Display.windowProc(long, long, long, long) line: 4873	
	OS.DefWindowProcW(long, int, long, long) line: not available [native method]	
	OS.DefWindowProc(long, int, long, long) line: 2454	
	Shell.callWindowProc(long, int, long, long) line: 497	
	Shell(Control).windowProc(long, int, long, long) line: 4253	
	Shell(Canvas).windowProc(long, int, long, long) line: 341	
	Shell(Decorations).windowProc(long, int, long, long) line: 1598	
	Shell.windowProc(long, int, long, long) line: 2038	
	Display.windowProc(long, long, long, long) line: 4886	
	OS.DispatchMessageW(MSG) line: not available [native method]	
	OS.DispatchMessage(MSG) line: 2459	
	Display.readAndDispatch() line: 3655	
	Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2640	
	Workbench.runUI() line: 2604	
	Workbench.access$4(Workbench) line: 2438	
	Workbench$7.run() line: 671	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 664	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	AstoriaNavigatorApp.start(IApplicationContext) line: 25	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 369	
	EclipseStarter.run(String[], Runnable) line: 179	
	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: 620	
	Main.basicRun(String[]) line: 575	
	Main.run(String[]) line: 1408	
	Main.main(String[]) line: 1384
Comment 6 Paul Webster CLA 2012-05-07 14:18:48 EDT
(In reply to comment #5)
> Paul,
> 
> Is this what you're looking for?

Yes, thanx
PW
Comment 7 Stefan Mücke CLA 2012-05-21 07:29:37 EDT
I have found the code that causes this behavior, but I cannot explain it yet; the following code was added in commit 1cf26be25448032659336f449476fe5108a2f4a1 as a fix for bug 333577:

    WorkbenchWindow.java

    protected boolean canHandleShellCloseEvent() {
        [...]

        // Ensure that any pending 'Close' event are flushed
        // before opening any dialogs
        while (Display.getCurrent().readAndDispatch())
            ;

        [...]
    }

Bug 349484 should be closed as a duplicate of this bug.
Comment 8 Dylan McReynolds CLA 2012-05-21 14:09:57 EDT
Interesting. For us, it's definitely related to a view that has the Browser control in it. Other views do not exhibit the behavior.
Comment 9 Stefan Mücke CLA 2012-05-21 14:38:34 EDT
(In reply to comment #8)
> Interesting. For us, it's definitely related to a view that has the Browser
> control in it. Other views do not exhibit the behavior.

Yes, it's definitely related to the Browser. I am having exactly the same problem as you described in comment 1.

When I remove the additional spinning of the event loop in canHandleShellCloseEvent, the problem disappears.

For some reason, the WorkbenchWindow receives two WM_CLOSE messages, but so far I couldn't find out why. Maybe the Alt+F4 keypress is processed twice, once in the browser and once by SWT.

A not-so-nice workaround would be to use a flag to detect a nested call to canHandleShellCloseEvent and ignore it:

    protected boolean canHandleShellCloseEvent() {
        // Workaround for bug 345600
        if (isInCloseEvent)
            return false;

        if (!super.canHandleShellCloseEvent()) {
            return false;
        }

        isInCloseEvent= true;
        try {
            // Ensure that any pending 'Close' event are flushed
            // before opening any dialogs
            while (Display.getCurrent().readAndDispatch())
                ;
        } finally {
            isInCloseEvent= false;
        }

        // let the advisor or other interested parties
        // veto the user's explicit request to close the window
        return fireWindowShellClosing();
    }

I have already tested this workaround on my machine and it worked fine.
Comment 10 Dylan McReynolds CLA 2012-05-21 14:41:21 EDT
Nothing other than the same stack trace listed in Comment #1.
Comment 11 Paul Webster CLA 2012-05-22 09:37:41 EDT
Passing to SWT for comment.  Is there special handling on windows that fires a second WM_CLOSE event when the browser is embedded?

PW
Comment 12 Justin Dolezy CLA 2014-10-09 16:13:09 EDT
Does this looks like a duplicate of https://bugs.eclipse.org/bugs/show_bug.cgi?id=204192 ?

I'm guessing so as our 3.7.1 based app exhibits the close-when-browser-open problem, but not in our e4/Kepler version, and 204192 was fixed in 4.2
Comment 13 Arun Thondapu CLA 2014-10-13 08:36:59 EDT
(In reply to Justin Dolezy from comment #12)
> Does this looks like a duplicate of
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=204192 ?
> 
> I'm guessing so as our 3.7.1 based app exhibits the close-when-browser-open
> problem, but not in our e4/Kepler version, and 204192 was fixed in 4.2

Thanks for the update! Marking it as duplicate, can be reopened in case there is evidence to prove otherwise...

*** This bug has been marked as a duplicate of bug 204192 ***