Edit: as it happens Tom has already written about this very problem, although approached from the splash screen angle. His solution is equally valid but I will keep this post around simply because it more specially calls out the threading issue that needs to be addressed.
Eclipse 3.3 brought some pretty substantial changes to the Eclipse startup process, many of which were to accommodate having a splash screen implemented in SWT. The most fundamental of these changes is that the Workbench initialization procedure is done on a non-UI thread while the UI thread spins the event loop in order to paint the splash. The initialization process often posts runnables back to the UI thread periodically to do various initialization segments that touch the UI but otherwise it’s done on it’s own thread so that the splash remains responsive. We’ve taken steps to ensure that any client-implementable API is still invoked on the UI thread as well to ensure backwards compatibility. Having said that, there are some patterns (which were never properly API) that used to work which no longer do.
These problems are most often encountered by RCP developers who’re trying to affect the UI during startup via a background thread using asyncExec or syncExec. Previous to 3.3 any runnable posted in this way would not be run until the Workbench had finished initializing or the app spun the loop manually. Given that we’re spinning the event loop early for all clients now it was important that any runnable posted would still not be run until after the workbench had finished initializing – running them early could cause all sorts of grief for clients that were assuming that the Workbench had already been created and initialized. The side effect of this, however, is that RCP developers who were creating applications that were interactive during initialization (providing a log in window for instance) could no longer spin the event loop themselves and expect background runnables to run.
We plan on providing some kind of API in 3.4 to more easily address this (see bug 182176) but in the mean time take a look at the following WorkbenchWindowAdvisor implementation.
The pattern, in a nutshell, is as follows. The RCP app spawns a background thread to do some form of grunt work during initialization. The RCP app then spins the event loop, periodically checking to see of the background thread has finished by seeing if it has created a certain runnable. If it has, then the runnable is invoked on the UI thread and the RCP app stops spinning the loop.









4 responses so far ↓
1 Volker Wegert // Aug 19, 2007 at 1:52 am
Nice. Unfortunately, “just for the splash screen”, you (perhaps not you personally, but “the developers”) broke the launcher and didn’t get it fixed in time for the 3.3 release. Bad idea. Really bad idea…
2 Z // Aug 21, 2007 at 12:42 pm
Hi Kim,
I stumbled upon your blog looking for a solution to a specific eclipse rcp problem. Perhaps you know the answer?
Basically, it boils down to; how is an rcp suppose to handle the instance location or workspace directory?
I need to implement switch workspace in my rcp. Is there any way to get the last used instance location?
My idea is to add the IDEActionFactory.OPEN_WORKSPACE action to the file menu of my rcp. But when i start the rcp the first time it will not remember which instance location it was on previously (like eclipse ide does).
How is this usually done?
3 Ed Thomson // Aug 30, 2007 at 11:50 am
This is a problem for at least some of us writing RCP apps. Our problem isn’t in the splash screen, it’s actually after the splash screen is closed:
Despite the name, WorkbenchAdvisor.postStartup() is called while the workbench is still initializing, and the UI is still deferring asyncExec() calls.
We hacked a solution where postStartup() puts a Runnable onto the UI queue. (By starting another Thread which calls Display.asyncExec(). Runnables insides Runnables! It’s ugly!)
Thanks for addressing the workbench startup for 3.4.
4 Ali // Oct 6, 2007 at 1:30 pm
Hi Kim.
Thanks for your article. I have started using the new splashscreen and am doing login in that phase. A problem/question that I have is the following: Based on some information, I may need to force a restart of workbench but can’t call PlatformUI.getWorkbench().restart() in my SplashHandler code, so what would you suggest?
Thansk,
Ali.
Leave a Comment