Avoid useless Plugin Initialization and/or Class Loading

Here’s a tip for initializing your plugins or any other singleton-like repository only when needed.

Consider a code like this:

if (isConfigurable()) {
  Bundle bundleCopy = bundle;
  Preferences[] preferencesCopy = new Preferences[1];
  preferencesCopy[0] = new org.eclipse.core.internal.
			preferences.legacy.PreferenceForwarder(
			this, bundleCopy.getSymbolicName());
  return preferencesCopy;
}
return null;

Do you see what’s wrong there?

The problem is that if your #isConfigurable is always FALSE then your code still:

  1. loads PreferencesForwarder class
  2. initializes all PreferencesForwarder’s static variables
  3. forces Preferences plugin to load

Always, if possible and makes sense, isolate your class loading into a simple Runnable inner class if there is some static init or plugin activation trigger involved!

Then the code would become:

if (isConfigurable()) {
  final Bundle bundleCopy = bundle;
  final Preferences[] preferencesCopy = new Preferences[1];
  Runnable innerCall = new Runnable() {
    public void run() {
      preferencesCopy[0] = new org.eclipse.core.internal.
			       preferences.legacy.PreferenceForwarder(
				 this, bundleCopy.getSymbolicName());
    }
  };
  innerCall.run();
}
return null;

When you think of it – this pattern is somewhat similar to the singleton pattern implementation – the one of the very few thread-safe and fast singleton patterns that is bugfree and truly lazy!

Quoting wonderful singleton impl from wikipedia:

public class Singleton {
   private Singleton() {}
   private static class SingletonHolder {
     private final static Singleton INSTANCE = new Singleton();
   }
   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
 }

(OK, to be fully honest, since java1.5 you can also trust volatile flags but – trust noone, use the old stuff:P)

For the reference, the PreferencesForwarder example was taken from the org.eclipse.core.runtime.Plugin#getPluginPreferences class and modified a bit.

UPDATE: This post is not fully correct! Never assume something to be true even if it comes from a trustworthy source like eclipse core runtime source. Please see the comments for explanation!

3 Comments

  1. In what circumstances do you think that PreferenceForwarder will load from the first example

    if (isConfigurable()) {
    Bundle bundleCopy = bundle;
    Preferences[] preferencesCopy = new Preferences[1];
    preferencesCopy[0] = new org.eclipse.core.internal.
    preferences.legacy.PreferenceForwarder(
    this, bundleCopy.getSymbolicName());
    return preferencesCopy;
    }
    return null;

    My understanding is that classloading on most JVMs is so lazy that it will only happen if the condition is evaluated to true. A few tests on different JVMs (Sun 1.4.2, 5, 6 and IBM 1.4.2, 6) with -verbose:class confirmed this behavior for me.

    It is not a big deal, but I am a little concerned with adding complexity (although not that much) for no reason.

    Posted December 19, 2007 at 9:03 pm | Permalink
  2. Mark: Haha! How embarrassing, you were right :)

    Plugin source code has a comment regarding this and it was clearly misleading:
    // Performance: isolate PreferenceForwarder into
    // an inner class so that it mere presence
    // won’t force the PreferenceForwarder class
    // to be loaded (which triggers Preferences
    // plugin activation).

    True, of course it makes sense that class load happens only when it’s actually needed.

    Now I don’t see any reason why this Runnable is in #getPluginPreferences after all.

    Posted December 20, 2007 at 11:43 am | Permalink
  3. Sometimes respective source code like eclipse runtime is so trustworthy that one stops thinking if it’s really correct :P

    Posted December 20, 2007 at 11:47 am | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Anti-Spam Protection by WP-SpamFree