In my IApplication, I am trying to set-up an invisible workbench (e.g., just initialize the workbench and immediately close so that ui libraries that does not need to be executed by the UI thread can be used later on --- in other words, ui plug-ins are pre-loaded), with the following code:

public class SolsticeClientApplication implements IApplication
{
@Override
// Suppressed due to missing library annotation.
public Object start(@SuppressWarnings("null") IApplicationContext context) throws Exception
{
int okStatus = IApplication.EXIT_OK;
// It turns out that we have to create the display and the workbench on the main thread of
// the headless application. It makes sense for the display as the main thread needs to
// become the UI thread, however for the workbench, if we create an run it in another
// thread, it just fails without any warning at all.
final Display display = PlatformUI.createDisplay();
int retCode = PlatformUI.createAndRunWorkbench(display, new HeadlessAdvisor());
// Signal that the workbench is created.
// TODO According to above comment, we are blocking the UI thread until the application
// is over. Is that alright?
// I guess this is fine as we are not really using the UI thread in the client
// application. In any case we should not be invoking any code that uses the UI thread.
// Rather, we are only using data structures and methods that are in ui packages due to the
// way they are created, but have nothing to do with the UI thread.
synchronized (SolsticeClient.getInstance())
{
SolsticeClient.getInstance().wait();
}
return okStatus;
}
@Override
public void stop()
{}
}

where HeadlessAdvisor is implemented as:

public class HeadlessAdvisor extends WorkbenchAdvisor
{
public HeadlessAdvisor()
{}
@Override
public @Nullable
String getInitialWindowPerspectiveId()
{
return null;
}
// It turns out that we have to override this method, as it normally does a lot of work in the
// actual implementation (WorkbenchAdsivor). It would create a full-fledged workbench and then
// return some boolean representing whether the workbench creation was successful or not.
// However, in our case, returning 'true' just represents that for our purposes the workbench
// creation was successful, and we don't create anything.
@Override
public boolean openWindows()
{
return true;
}
@Override
public void postStartup()
{
super.postStartup();
// close(..) is the call that actually closes the workbench.
try
{
// The following method throws an exception (NullPointer?) in the internal Eclipse code:
// Workbench:1121 ((IpresentationEngine) engine.stop();) For all our purposes, this
// exception seems completely harmless as long as it is caught (the workbench still gets
// closed). I think that this is due to the fact that we are not actually using any
// workbench elements rather just trying to load the related plug-ins (for later
// access).
PlatformUI.getWorkbench().close();
}
catch (Exception e)
{
// Log the exception.
}
}
@Override
public void postShutdown()
{
// This method is called by close(..)
super.postShutdown();
}
}

When I execute this IApplication, I get the following exception (as also explained in the code as comments above):

null
at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1121)
at org.eclipse.ui.internal.Workbench.access$16(Workbench.java:1001)
at org.eclipse.ui.internal.Workbench$17.run(Workbench.java:1182)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.Workbench.close(Workbench.java:1180)
at org.eclipse.ui.internal.Workbench.close(Workbench.java:1153)
at com.kivancmuslu.www.solstice.client.HeadlessAdvisor.postStartup(HeadlessAdvisor.java:44)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2548)
at org.eclipse.ui.internal.Workbench.access$7(Workbench.java:2431)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:586)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:543)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at com.kivancmuslu.www.solstice.client.SolsticeClientApplication.start(SolsticeClientApplication.java:85)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
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:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)

As I get this error (logged by the catch(..) block above), I believe at this moment IWorkbench.close(..) completed running (although by throwing an exception). In my execution logs, I see that postShutdown(..) method is called back, so my belief that the workbench is closed increases even more. Finally, if I run the same application as an Eclipse IDE application (instead of JUnit plug-in test) for manual testing, the above code (PlatformUI.createAndRunWorkbench(..)) executes and completes with success and my program works just fine (although I receive almost the same exception).

Any idea why would PlatformUI.createAndRunWorkbench(..) get stuck? Can it be something dependent on the JUnit plug-in tests (as the normal execution works fine)? Any ideas on how to fix it? Any insight on the problem is greatly appreciated.

Let me know if you need any more information about the program, code, etc. My apologies if this is the wrong forum to post, please feel free to move it to the better suited forum. Thanks in advance.