| Summary: | Dialogs opened with Method.invoke("open") cause UIThreadTerminatedError on page refresh | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [RT] RAP | Reporter: | Adrian Stefanescu <stefanescu.a> | ||||
| Component: | RWT | Assignee: | Project Inbox <rap-inbox> | ||||
| Status: | RESOLVED INVALID | QA Contact: | |||||
| Severity: | critical | ||||||
| Priority: | P3 | ||||||
| Version: | 1.2 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Adrian Stefanescu
Here is the example that can be used to reproduce this bug:
Dlg class:
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.widgets.Shell;
public class Dlg extends Dialog
{
public Dlg( Shell parentShell )
{
super( parentShell );
}
}
Code that causes the error called from a select:
Dlg dlg = new Dlg( getSite().getShell() );
Method m = dlg.getClass().getMethod( "open", new Class[0] );
m.invoke( dlg);
On page refresh while the dialog is opened it causes the current session to break and the browser needs to be reopened to start a new session.
java.lang.reflect.InvocationTargetException
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)
Caused by: org.eclipse.rwt.internal.lifecycle.RWTLifeCycle$UIThreadTerminatedError
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.sleep(RWTLifeCycle.java:308)
at org.eclipse.swt.widgets.Display.sleep(Display.java:790)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:837)
at org.eclipse.jface.window.Window.open(Window.java:812)
and also this exception:
java.lang.IllegalStateException: The context has been disposed.
at org.eclipse.rwt.internal.service.ServiceContext.checkState(ServiceContext.java:154)
at org.eclipse.rwt.internal.service.ServiceContext.getStateInfo(ServiceContext.java:104)
at org.eclipse.rwt.internal.service.ContextProvider.getStateInfo(ContextProvider.java:166)
at org.eclipse.rwt.SessionSingletonBase.getInstance(SessionSingletonBase.java:84)
at org.eclipse.ui.internal.Workbench.getInstance(Workbench.java:466)
at org.eclipse.ui.internal.ExceptionHandler.handleException(ExceptionHandler.java:60)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2489)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2444)
at org.eclipse.ui.internal.Workbench.access$5(Workbench.java:2295)
at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:514)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:497)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:157)
at com.atoss.atc.web.core.Application.createUI(Application.java:18)
at org.eclipse.rwt.internal.lifecycle.EntryPointManager.createUI(EntryPointManager.java:92)
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:231)
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:119)
at java.lang.Thread.run(Unknown Source)
Exception in thread "UIThread [8m0h4a3my6eo]" java.lang.IllegalStateException: The context has been disposed.
at org.eclipse.rwt.internal.service.ServiceContext.checkState(ServiceContext.java:154)
at org.eclipse.rwt.internal.service.ServiceContext.getRequest(ServiceContext.java:82)
at org.eclipse.rwt.internal.service.ContextProvider.getRequest(ContextProvider.java:129)
at org.eclipse.rwt.internal.service.ContextProvider.getSession(ContextProvider.java:148)
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.setShutdownAdapter(RWTLifeCycle.java:350)
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.access$0(RWTLifeCycle.java:347)
at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:133)
at java.lang.Thread.run(Unknown Source)
This does the same as the code that causes the error except this one works and the page gets refreshed. Dlg dlg = new Dlg( getSite().getShell() ); dlg.open(); Ok, the real problem is when I try to run some dialogs stored in some jar files that need to be called with invoke but the example above causes the same problem. A modal dialog that is opened with "invoke"(direct or indirect to a method that later calls open) will cause that thread error on refresh. Created attachment 166056 [details]
Controls demo patch
This patch opens LoginDialog in Controls Demo -> DialogTab with reflection. Use it to reproduce the bug. When the dialog is still open, browser reload leads to UIThreadTerminatedError thrown by RWTLifeCycle#switchThread().
In RAP it is vital for the application restart not to prevent the ThreadDeath exception from propagation. Add this code in catch clause of InvocationTargetException to survive the restart:
....
try {
method.invoke(....);
} catch( InvocationTargetException e ) {
if( e.getTargetException() instanceof ThreadDeath ) {
throw ( ThreadDeath )e.getTargetException();
}
}
....
Tested with RAP from CVS HEAD.
|