equinox
dynamic plugins > current plugin model

 
An overview of the 2.1 plugin model at runtime.

The Plug-in Registry

When the Eclipse Platform starts, it first discovers all available plug-ins and fragments. The install/update component of Eclipse and a user-defineable plug-in path are used to determine directories where to plug-ins and fragments can be found. Each plug-in/fragment directory may contain exactly one manifest file named plugin.xml or fragment.xml. If a directory contains both files, only the plugin.xml file is used.

Once the discovery is completed, the platform parses the discovered manifest files and builds a plug-in registry. Manifests which cannot be loaded are skipped and the failure is noted in the platform's log (typically under the <workspace>/.metadata directory). The registry is then resolved. That is, it is examined to ensure the structure is useful and sane, and its structures are cross linked. Resolution includes the following steps:

An error message is logged if any problems are encountered and the offending element is removed from the plug-in registry. This allows Eclipse to continue running even if there are minor problems. The resulting plug-in registry is available via the org.eclipse.core.runtime plug-in's API. The whole plug-in registry is available through IPluginRegistry and individual plug-ins can be examined with IPluginDescriptor.

Because these plug-ins define the running Eclipse, additions, deletions or modifications of plug-ins are not detected after start-up. Eclipse must be shut down and restarted to detect these changes.

Plug-in Activation

When Eclipse starts up, only those plug-ins needed to build the plug-in registry and get things started are activated. All other plug-ins (the vast majority of plug-ins) remain dormant. When something happens causing the code within a plug-in to be loaded, that particular plug-in is activated. That is, classloading is the only trigger for plug-in activation. Plug-ins are only activated if the class loaded comes from the plug-in's local classpath (i.e., one of its libraries). Loading classes from a prerequisite does not count. This is the basis for Eclipse's lazy plug-in activation policy.

Many things can happen without activating a plug-in. In particular,

Once a plug-in is activated it remains active until Eclipse shuts down. When Eclipse does shut down, all plug-ins are shut down in a dependents-first order. For example, if plug-in A requires plug-in B, then plug-in A will be shut down before plug-in B.

Plug-in Classloading

Libraries define the local classpath of a plug-in. Each library entry translates into an entry on the classpath of the plug-in's classloader. Earlier we discussed the concept of a code vs. a resource library. Resource libraries are loaded by a resource loader and do not figure into the strict classloading model.

Classloading in Eclipse follows the P-S-P model. That is, Parent-Self-Prerequisites.

Parent
Each plug-in classloader has the Eclipse boot plug-in's classloader as its parent. The boot plug-in's loader's parent is the system classloader. Note that the standard Java AppClassloader? (the one used to load the class containing main()) is not added to the classloading chain. As a result, the jars added to the JVM's classpath are ignored. Jars added to the JVM's bootclasspath are part of the system classloader and are considered during plug-in classloading.
Self
Self considers the libraries defined as part of this plug-in. All code libraries contributed by fragments to this plug-in are also considered. Libraries contributed by fragments appear after those contributed in the plug-in manifest. Libraries from the same manifest appear on the class path in the same order in which they were declared.
Prerequisites
Finally the exported libraries of the plug-in's prerequisites are considered. Prerequisites are queried in the order in which they were declared with the exception of the runtime plugin (org.eclipse.core.runtime). All plug-ins automatically have the runtime plug-in added to their prerequisite list as the first prerequisite. All imports of the runtime plug-in are ignored.

Note that prerequisite consultation is transitive. When locating a class, a prerequisite plug-in will follow the same (though optimized) P-S-P model. Since all plug-in classloaders have the same parent, prerequisite loaders need not look there. Similarly, plug-ins which occur repeatedly in the transitive closure of the prerequisite graph are consulted at most once. Finally, prerequisite re-exporting rules are followed as described above.

Plug-in Data

The Eclipse Platform makes certain assumptions about the physical structure of a plug-in. Each plug-in or fragment is typically stored in a separate directory under a directory named plugins under your Eclipse install directory. The name of this directory is usually the same as the plug-in's id (though it may have the version number appended to it). In addition to the plugin.xml or fragment.xml file, there may be any number of folders under the plug-in's root folder.

Since Eclipse can be run on a wide range of machine configurations (i.e., operating system, window system, ...) it needs a way of managing different forms of the same data (e.g., shared libraries). Eclipse provides four variables for use in library statements which resolve to parts of the current machine configuration.

os
The operating system on which Eclipse is currently running (e.g., win32, linux, solaris, ...)
ws
The window system being used for the Eclipse UI (e.g., win32, motif, gtk, ...)
arch
The type of processor in the machine (e.g., x86, ppc, sparc, ...)
nl
The current locale (e.g., en_CA, jp_JP, ...)

So, for example, if your plug-in uses windowing system-specific features, it may be necessary to provide a different library for each configuration. Using $ws$/<library name> in your plug-in manifest file directs Eclipse to look for the library in a window system directory with the same name as the current window system. The org.eclipse.swt plug-in uses this mechanism as follows:

  <runtime>
    <library name="$ws$/swt.jar">
      <export name="*"/>
    </library>
  </runtime>

The SWT plug-in has a series of directories of the form ws/<windowing system>/ (e.g., ws/win32, ws/gtk, ws/motif). Each of these directories contains a different version of swt.jar. If you are working in an Eclipse environment in a win32 windowing system, the library name $ws$/swt.jar will match ws/win32/swt.jar. Note that in practice any given Eclipse install will have only one swt.jar (the one that matches the install). The jars are actually contributed by window system-specific fragments. This allows the common part of a plug-in to be put in the plug-in and have only the window system code in a fragment.

Registry Life Cycle

Plugins currently have two states:

Accordingly, the current (2.1) Eclipse plugin lifecycle events are:

Sartup
When a plugin is activated its startup() method is called. Plugins should do any lightweight initialization at this point. Walking of this plugin's extension points is sometimes done here. Heavyweight initialization should be deferred until function requiring the initialized state is required.
Shutdown
When a plugin is deactivated its shutdown() method is called. This signals the plugin to free any resources it has allocated. They also have the option of saving any state they may have available. (note that the org.eclipse.core.resources plugin also provides some workspace save lifecycle via the ISaveParticipant interface. This is separate from the plugin lifecycle model.)