Monday, January 6, 2014

java.lang.IllegalStateException: "Workbench has not been created yet"

As an end user, if you are facing this issue. Please try out the following options.

1. Try to open eclipse in clean mode and select a new workspace.
  eg: eclipse -clean

2. Try to delete workspace .metadata folder and open in clean mode. In this case, you will lose workspace preferences and projects, you need to re-import them.


As an eclipse developer, we need to understand more about this issue to provide a solution.

When do we get this issue ?

If your plug-in is trying to access PlatformUI.getWorkbench() before workbench is created fully.

Example: This is my code in the MyActivator.start()


Display.getDefault().syncExec(new Runnable() {
          @Override
          public void run() {
                                                                                PlatformUI.getWorkbench().getActiveWorkbenchWindow().addPerspectiveListener(pHandler);
                                         }
                                           });


As a result of this, I might face java.lang.IllegalStateException: "Workbench has not been created yet" error.

If we look at the implementation of a workbench class.

  /**
     * Returns the workbench. Fails if the workbench has not been created yet.
     *
     * @return the workbench
     */
    public static IWorkbench getWorkbench() {
        if (Workbench.getInstance() == null) {
            // app forgot to call createAndRunWorkbench beforehand
            throw new IllegalStateException(WorkbenchMessages.PlatformUI_NoWorkbench);  //here it’s throwing exception
        }
        return Workbench.getInstance();
    }


So how do we address this issue then ?

Let’s try out this.

while(!PlatformUI.isWorkbenchRunning() ) { //If workbench is not running keep checking for it.
                               
}

//Do your actual work here


But there is a problem with it, as per the Eclipse workbench documentation, Note that this method may return true while the workbench is still being initialized, so it may not be safe to call workbench API methods even if this method returns true.

That means, even though workbench is not fully initialized it will return true, that is something which we don't want.

How do I stop activator.start() execution until workbench is fully created ?

Below is the way which was discussed @ https://bugs.eclipse.org/bugs/show_bug.cgi?id=49316

 public class WorkbenchState implements IStartup
  {
    private static boolean started = false;
    public void earlyStartup ()
    {
        Display.getDefault ().asyncExec (new Runnable ()
        {
            public void run ()
            {
                started = true;
            }
        });
    }
   
    public static boolean isStarted ()
    {
        return started;
    }
  }


Now, in my MyActivator.start(), I will try to invoke in the following way.

While (WorkbenchState.isStarted()) {
   //do your actual work here
}


As we can understand one thing from above code is, IStartup earlyStartup () will be invoked after workbench is initialized completely.

Above approach suits for standard eclipse plug-ins, if you guys are developing Eclipse RCP. You can do the following.

WorkbenchAdvisor has a postStartup() method, this will be invoked only after workbench is initialized completely.

Example:

MyApplicationWorkbenchAdvisor extends WorkbenchAdvisor
{
    public static isStarted = false;
      public void postStartup() {
                                isStarted = true;
                }
               
 public static boolean isStarted ()
    {
        return isStarted;
    }

}


//In your plug-in access in the following way.
While (MyApplicationWorkbenchAdvisor.isStarted()) {
   //do your actual work here

}


No comments:

Post a Comment