Over a million developers have joined DZone.

Gracefully Loading a Heavy Plugin

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

Here's the challenge: I have a plug-in which may take more than a few seconds to load. That's not a problem if the plug-in is loaded when the platform starts since the user waits for platform to load anyway. However, if the plug-in is loaded on-demand, after the platform is already started, the user may experience an unexplained freeze. 

To overcome this behavior, it is best to use some progress dialog with a monitor when starting your plugin. This is simple, however, the less-than-trivial question is: how to determine if the platform is starting?  

Those with some knowledge of Eclipse would simply direct me to a very simple API call:

PlatformUI.isWorkbenchRunning()

One major disadvantage.. this is useless, since it will return true when the platform is still loading as well. It is considered running at this point.

Searching in the Eclipse newsgroups portal, I came across another idea:

Bundle b = Platform.getBundle("org.eclipse.swt");
if (b==null || b.getState() != Bundle.ACTIVE) { 
   System.out.println("no UI..."); 
}

This doesn't work, since SWT is already resolved when the splash screen is shown. You can test other bundles, if you'd like, but I find it hard to believe you'll discover any well-defined and consistent difference between the two situations: loading upon launch and loading after it is complete.

My next idea was to check the visibility of the default shell. Nope, it is considered visible at startup. I tried checking for the existence of workbench visual parts and, guess what, they're already there in both cases. After some trial and error I found a very simple way of doing that. One of the distinct features when the splash screen is showing is that you don't see a menu-bar. From that I derived the following test:

Display.getCurrent().getActiveShell().getMenuBar() == null

This will return true when the platform is still launching and a splash screen is shown. Putting it all together and adding all the null checks I could think of, I wrote the following method for checking if the shell is already open and return it if it is:

private Shell findStartedShell() {
   Shell result = null;
   final Display currentDisplay = Display.getCurrent();
   if (currentDisplay != null) {
      result = currentDisplay.getActiveShell();
      if ((result != null) && (result.getMenuBar() == null)) {
         result = null;
      }
   }
   return result;
}


 

I used a ProgressMonitorDialog to show the progress and an IRunnableWithProgress to implement the lengthy startup process. Eventually, the plugin Activator start method would look like this:

public void start(final BundleContext context) throws Exception {
   super.start(context);
   plugin = this;
   final IRunnableWithProgress statupOperation = 
      new IRunnableWithProgress() {

      public void run(final IProgressMonitor monitor) throws
         InvocationTargetException, InterruptedException {
         // do your initialization here
         // use the monitor to set the task name 
         // and report progress

      }
   };

   final Shell activeShell = findStartedShell();
   if (activeShell != null) {
      final ProgressMonitorDialog progressMonitorDialog = 
         new ProgressMonitorDialog(activeShell);
      progressMonitorDialog.run(false, false, statupOperation);
   } else {
      statupOperation.run(new NullProgressMonitor());
   }
} 


The above will do exactly what we were looking for: if the platform is launching, it will proceed with normal startup (the splash screen shows the progress of loading all the plugins) and, if the platform is already loaded, it will show a progress dialog.

Found a better way of doing that?  Let me know in the comments.

From http://zvikico.typepad.com

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}