| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=charset=ISO-8859-1"> |
| <title>Eclipse 3.0 Runtime</title> |
| <link rel="stylesheet" href="/default_style.css"> |
| </head> |
| <body link="#0000ff" vlink="#800080"> |
| |
| <p align="right"><img src="file:///D|/equinox/ngibmcpy.gif" alt="Copyright IBM Corporation and others 2000, 2003." border="0" width="324" height="14"></p> |
| <table border="0" cellspacing="0" cellpadding="2" width="100%"> |
| <tbody> |
| <tr> |
| <td align="Left" valign="Top" colspan="2" bgcolor="#0080c0"><b><font face="Arial,Helvetica"><font color="#ffffff"> |
| Eclipse Corner Article</font></font></b></td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <div align="Left"> |
| <h1><img src="file:///D|/equinox/prototype/plugins/images/Idea.jpg" height="86" width="120" align="Center"> |
| </h1> |
| </div> |
| |
| <h1 align="Center">Inside and Beyond the Eclipse 3.0 Runtime</h1> |
| <blockquote> |
| <p><b>Summary</b><br> |
| <center> |
| <b>This is a draft document. </b> |
| </center> |
| <br> |
| The Eclipse Platform is based on the notion of plug-ins. Plug-ins are a simple |
| but powerful mechanism that allow developers and users to construct complex |
| tool sets by composing functionality (i.e., plug-ins). There are of course |
| a number of subtleties in how plug-ins are defined and how they interact. |
| This article attempts to demystify plug-ins and make it easier to create and |
| manage Eclipse Platform configurations.</p> |
| <p> </p> |
| <p><b> By Jeff McAffer, IBM OTI Labs</b><br> |
| <font size="-1">January 27, 2004</font></p> |
| </blockquote> |
| |
| <hr width="100%"> |
| <h2>Preamble</h2> |
| <p>This document is a direction statement for the Eclipse runtime based on an |
| extended <a href="http://www.osgi.org">R3.0 OSGi framework specification</a>. |
| While most of the function and API described here is included in Eclipse 3.0, |
| it is not officially supported. Rather, Eclipse 3.0's official runtime API is |
| largely unchanged from Eclipse 2.1. Subsequent releases of Eclipse will codify |
| the new behaviour described here. Early adopters and other interested parties |
| are free to exploit the new capabilities but should be aware that some API may |
| change over time. </p> |
| <p>This document makes no attempt to relate "new world" runtime concepts/mechanisms |
| to classic mechanisms. This is left to a companion migration guide document.</p> |
| <p>Throughout this document we use the terms <i>plug-in</i> and <i>bundle</i> |
| interchangeably unless we are refering to the actual <tt>Plugin</tt> or <tt>Bundle</tt> |
| classes. Just as in Eclipse 2.1, some plug-ins/bundles may specify extensions |
| or extension points and some may not.</p> |
| <p><font color="#FF0000">Note: The manifest markup and code fragments in this |
| document are preliminary and subject to change prior to the final release of |
| Eclipse 3.0</font></p> |
| <p></p> |
| <h2>Why Plug-ins?</h2> |
| |
| |
| <p>One of the main design points of the Eclipse Platform is that it is extremely |
| extensible. Another is that it is uniform. The Eclipse plug-in model is key |
| in satisfying both of these goals. A plug-in is a piece of functionality which |
| can be added to the runtime. Tools and applications are constructed by creating |
| one or more plug-ins. How tools or applications are factored into plug-ins depends |
| on the nature of the tool or application. </p> |
| <p>Eclipse itself, for example, is made up entirely of plug-ins: some 50 or so |
| in all. Even the runtime which manages plug-ins, is itself a plug-in! Plug-ins |
| interact via well defined API's. Since everything is a plug-in and plug-ins |
| interact via public interfaces, all plug-ins are equal in the system. There |
| are no plug-ins which get special treatment or privileges. For example, the |
| Workbench UI is a plug-in which presents the resource model defined by the Resources |
| plug-in. Since the Workbench accesses the Resources plug-in only via API, all |
| other plug-ins have exactly the same opportunities for manipulating resources.</p> |
| <p>It follows from this, that capabilities are added to the Platform incrementally, |
| by adding plug-ins. Each new plug-in ties into the API of existing plug-ins |
| and provides new functionality. Still other plug-ins then build on the API of |
| these new plug-ins to add still more functionality to the Platform. And so on...</p> |
| |
| |
| <p>Another design point that makes Eclipse extremely extensible is its policy |
| of laziness. Only those plug-ins with code that is actually being used are <i>activated</i>. |
| Lazy activation is key to supporting a large base of installed plug-ins, only |
| some of which are needed in any given user session. Until a plug-in's code is |
| loaded, it has a negligible memory footprint and impact on start up time.</p> |
| <h2>What is a plug-in?</h2> |
| <p>Eclipse <i>plug-ins</i> and OSGi <i>bundles</i> are synonymous and we use the |
| terms interchangeably. Fundamentally, plug-ins are a collection of files either |
| in a JAR file or a directory. In both cases they have the same internal structure. |
| The plug-in JAR or directory can be in the local filesystem or located/accessed |
| via a URL. The identity and execution characteristics of a plug-in are defined |
| by a <em>manifest file</em> called <code><strong>META-INF/MANIFEST.MF</strong></code>. |
| This is a standard Java JAR manifest file in the standard location within the |
| plug-in's file structure. An example of plug-in <tt>com.example.foo.jar</tt>'s |
| manifest is shown below. </p> |
| <blockquote> <XXX example here> </blockquote> |
| <p>The JAR or directory contains anything else the plug-in might need. Typically |
| this includes Java code, some read-only files, and resources such as images, |
| web templates, message catalogs, native code libraries, translation files, etc. |
| Most, though not all, plug-ins contribute executable code. Documentation plug-ins, |
| for example, contribute online help in the form of HTML pages registered with |
| the help system. If a plug-in does contain code it must either be written in |
| Java or be callable from Java. </p> |
| <p>The above plug-in manifest example is for a very simple plug-in which provides |
| no code. Below we highlight some commonly used facilities for specifying plug-in |
| interdependencies as well as code content. The complete details of manifest.mf |
| headers are given in the OSGi framework specification.</p> |
| <h3>Plug-ins with code</h3> |
| <p>Plug-ins which supply code must declare the location of the code on their <i>classpath</i>. |
| This is done using the Bundle-Classpath manifest header. It is specified as |
| a comma-separated list of entries where each entry is a path to the Java types |
| or resources which are to be loaded by a classloader. That is, </p> |
| <pre> Bundle-Classpath ::= path ( ’,’ path )* |
| path ::= <path name of nested JAR file or directory with "/"-separated components> | ’.’</pre> |
| <p>The path specified is evaluated relative to the plug-in's root and cannot resolve |
| to a location outside the scope of the plug-in (for example, "../../foo.jar" |
| is not allowed). In practice the entries take one of three forms:</p> |
| <dl> |
| <dl> |
| <dt>'.'</dt> |
| <dd>This is the default value if no classpath header is given. It puts the |
| root of the plug-in itself on the classpath. All files in the plug-in are |
| accessible via the classloader.</dd> |
| <dt>Directory path</dt> |
| <dd>These entries indicate a subdirectory in the plug-in (relative to the |
| root of the plugin) containing code and resources to load</dd> |
| <dt>JAR location</dt> |
| <dd>JAR entries indicate a JAR inside the plug-in which contains classes and |
| resources. The path to the JAR is relative to the root of the plug-in</dd> |
| </dl> |
| </dl> |
| <p>If the Bundle-Classpath header is omitted, the bundle classpath implicitly |
| includes '.'. If the header is included and does not include '.', the root directory |
| of the plug-in is not searched when looking for classes or resources. The classpath |
| specification below puts all classes/resources in <tt>foo.jar</tt> as well as |
| anything in the <tt>images</tt> directory on the classpath, in that order:</p> |
| <pre> Bundle-Classpath: foo.jar, images</pre> |
| <p>Note that while all combinations of classpath forms and running from JARs are |
| supported by the runtime, nested JARs and package directory structures not at |
| the root of a JAR both represent major deviations from the conventional Java |
| tooling support (e.g., javac does not support these structures). Accordingly, |
| the Eclipse tooling (e.g., PDE, JDT, Update/Install) may not fully support these |
| configurations.</p> |
| <p>The advanced section of this document outlines how to specify filters on classpath |
| entries to control their use in various execution environments. </p> |
| <h3>Explicit interplug-in dependencies</h3> |
| <p>There are two complementary ways of depending on something from outside a given |
| plug-in; Require-Bundle and Import-Package. Using the Require-Bundle manifest |
| header, plug-ins specify an explicit dependency on a specific bundle and version. |
| As such, the required bundles are placed logically on the dependent plug-in's |
| classpath. More discussion on this can be found in the exectuion section below. |
| For now it is sufficient to say that if you need code or resources from a particular |
| plug-in then you should specify a Require-Bundle header as follows:</p> |
| <pre> Require-Bundle ::= bundle (, bundle)* |
| |
| bundle ::= version [; match = constraint] |
| |
| constraint ::= perfect | equivalent | compatible | greaterequal</pre> |
| <p><strong></strong>If a plug-in A requires plug-in B, plug-in B is said to be |
| a prerequisite of plug-in A. Continuing our example, the manifest below shows |
| the manifest.mf expressing a dependency on <code>com.example.anotherplugin</code>.</p> |
| <blockquote> |
| <pre><example here></pre> |
| </blockquote> |
| <p>In this example, <code>com.example.myplugin</code> (My Plugin) can access any |
| of the classes in packages listed in the Provide-Package header of <code>com.example.anotherplugin</code> |
| (Another Plugin).</p> |
| <p>The Provide-Package header allows a plug-in to declare what parts of itself |
| it is willing to expose to those who depend on it using the Require-Bundle mechansim. |
| The form of a Provide-Package header is as follows:</p> |
| <pre> Provide-Package ::= package (, package)* |
| package ::= conventional Java package name</pre> |
| <p>Notice that the elements of the Require-Bundle header are qualified by a version |
| number and matching rule. Versions refine the dependencies between plugins and |
| help the runtime choose between different installations of the same plug-in. |
| In general the runtime picks the most recent version which matches given the |
| matching rule. Eclipse version numbers are a four part string of the form <strong><code>major.minor.service.tag</code></strong>. |
| Versions are compared using one of four matching rules.</p> |
| <dl> |
| <dl> |
| <dt><b>perfect</b></dt> |
| <dd>All four components of the version must match.</dd> |
| <dt><b>equivalent</b></dt> |
| <dd>major and minor must match and others must sort after</dd> |
| <dt><b>compatible</b> (default)</dt> |
| <dd>major must match and others must sort after</dd> |
| <dt><b>greaterequal</b></dt> |
| <dd>Any version which is a perfect match or sorts lexographically after</dd> |
| </dl> |
| </dl> |
| <p>Plug-in dependencies are transitive. That is, if Another Plugin requires some |
| plug-in, say Final Plugin, then My Plugin is not resolved unless both Another |
| Plugin and Final Plugin are present and resolved. This is easy to see since |
| Another Plugin is disabled if its prerequisites are not met (e.g., Final Plugin |
| is not present). Similarly, My Plugin is also disabled if its prerequisite, |
| Another Plugin, is not present. Circular dependencies are not permitted and |
| any plug-in involved in a cycle is disabled at runtime.</p> |
| <p><XXX need picture here></p> |
| <p>Class visibility through the dependency chain is not transitive unless explicitly |
| stated. That is, My Plugin cannot see the classes in Final Plugin unless Another |
| Plugin explicitly re-exports its import of Final Plugin. This effectively encapsulates |
| the implementation of Another Plugin. Where transitivity is required, the provide-packages |
| attribute of a Require-Bundle element is used to re-export the packages provided |
| by the required plug-ins. (try saying that a few times quickly!). For example, |
| </p> |
| <blockquote> |
| <pre>Require-Bundle: org.eclipse.swt; provide-packages="true"</pre> |
| </blockquote> |
| Finally, plug-in prerequisite elements can be made optional by adding the <code>optional="true"</code> |
| attribute (see below for an example). Marking an import as <code>optional</code> |
| simply states that if the specified plug-in is not found at runtime, the dependent |
| plug-in should be left enabled. This is used when a plug-in can be used in many |
| scenarios or it is reasonable to operate with reduced function. It allows the |
| creation of minimal installs that cover functional subsets. Authors of plug-ins |
| using optional prerequisites should take special care to avoid or handle the ClassNotFoundExceptions |
| which will occur when the optional plug-in is not present. |
| <pre> Require-Bundle: org.eclipse.swt; optional="true"</pre> |
| <h3>Implicit interplug-in dependencies</h3> |
| <p>The other mechanism for specifying dependencies on other bundles is expressed |
| through the Import-Package and Export-Package headers.</p> |
| <p><XXX expand this section with info from OSGi spec></p> |
| <h2>What are Extensions and Extension Points?</h2> |
| <ul> |
| <li><b>Extension points</b> allow other plug-ins to contribute information in |
| a well-defined manner. </li> |
| <li><b>Extensions</b> contribute information to the extension points of other |
| plug-ins.</li> |
| </ul> |
| <p><em>Extension points</em> are a mechanism used by plug-ins to indicate they |
| are willing to accept contributions from other plug-ins. An <em>extension</em> |
| is a plug-in's way of contributing information to these extension points. For |
| example, a UI plug-in might expose an extension point for menu actions. A plug-in |
| wishing to contribute an action to the UI would define an extension for the |
| UI's menu action extension point.</p> |
| <p>Extension points have a globally unique id constructed from the defining plug-in |
| id and a simple id specified in the extension point itself. The example below |
| is from the <code>org.eclipse.ui</code> plug-in. The full identifier of the |
| extension point is therefore <code>org.eclipse.ui.actionSets</code>. All extension |
| points have this relatively simple form.</p> |
| <blockquote> |
| <pre> <extension-point name="Action Sets" id="actionSets"/></pre> |
| </blockquote> |
| <p>The exact form of extensions is defined by the plug-in which defines the extension |
| point being extended. In the above example, the UI plug-in specifies what information |
| is needed to define the menu action as well as the form of that information. |
| For example, the UI needs a class it can instantiate and run when the menu entry |
| is selected. The type characteristics (e.g., superclass, interfaces) of the |
| class are also defined by the extension point itself. Such an extension is called |
| an <em>executable extension</em>. </p> |
| <p>Extensions and extension points are declared using XML in a file called plugin.xml |
| in the root of defining plug-in's file structure. This file has at top level |
| tag of <plugin> which has no attributes. The snippet below shows an example |
| extension and extension point in a plugin.xml file.</p> |
| <blockquote> |
| <pre><plugin> |
| <extension |
| point="org.eclipse.ui.actionSets"> |
| <actionSet |
| label="Example" |
| visible="false" |
| id="com.example.actions"> |
| <action |
| id="com.example.action1" |
| class="com.example.CoolAction" |
| icon="icons/action1.gif" |
| helpContextId="action1_context" |
| label="Action1" |
| </action> |
| </actionSet> |
| </extension> |
| |
| <extension-point id="foo" name="An Example"/> |
| </plugin></pre> |
| </blockquote> |
| <p>A plug-in can define any number of extension points and extensions. Further, |
| any given extension point may be extended by any number of extensions (including |
| 0). Extensions can extend extension points defined in their own plug-in or in |
| others. It follows, therefore, that extension points can accept extensions from |
| their own plug-in or other plug-ins. </p> |
| <p>Extending an extension point does not imply a dependency relationship. Rather, |
| it is a statement that if there is an extension point with the given id (point |
| attribute in the <strong><code>extension</code></strong> tag), add the given |
| extension. Otherwise, do nothing.</p> |
| <h4></h4> |
| <h2>What is a Fragment?</h2> |
| <p>Fragments allow optional functionality/content to be <strong>added</strong> |
| to existing plug-ins. For example, the base Eclipse contains only English messages. |
| Fragments are used to add message catalogs containing other languages (e.g., |
| French, Italian) without modifying the existing plug-ins. Note that fragments |
| can only add function/content to plug-ins. They cannot override that which the |
| plug-in already contains. Fragments are added to their host plug-ins in the |
| order in which the fragments were installed in the system. Fragments for missing |
| plug-ins are ignored.</p> |
| <p>It is not surprising to find that fragments are very similar to plug-ins; they |
| are defined using the same manifest files and the same directory structure. |
| They differ in the use of an additional header, Host-Bundle which identifies |
| the bundles (id, version and matching rule) which can host the given fragment. |
| Since this specification can match several bundles in a given configruation, |
| fragments may be bound to several host bundles at a time. Of course, any given |
| plug-in can have any number of fragments associated with it. </p> |
| <p>Fragments can contribute libraries, prerequisites, extension points or extensions |
| using standard syntax. These contributions are seamlessly merged into the fragment's |
| host plug-in(s). That is, extensions and extension points from a fragment appear |
| to come from/be part of (respectively) the base plug-in, libraries are put on |
| the base plug-in's classpath and prerequisites contribute to the plug-in's prerequisite |
| chain.</p> |
| <p>Below, is an example of a simple NL fragment for <code>com.example.myplugin</code>.</p> |
| <blockquote> |
| <pre>Bundle-Name: Example Add-on 1 Fragment |
| Bundle-Version: 2.0.2 |
| Bundle-GlobalName: com.example.myplugin.addon1 |
| Host-Bundle: com.example.myplugin; version=2.0.0; match=compatible |
| Bundle-Classpath: nl1.jar</pre> |
| </blockquote> |
| <p>This fragment contributes additional jars which contain translations of the |
| messages used by the plug-in itself. In this case the jar contains files named |
| according to the standard Java locale-based lookup strategy (e.g., message_en_US.properties, |
| message_jp_JP.properties). Since the jars are added to the plug-in's classpath, |
| the plug-in classloader will find these resources automatically. </p> |
| <h2>The Runtime Architecture</h2> |
| <p>All of the information we have discussed so far has dealt with physical plug-in |
| information stored in the Eclipse environment. We will now talk about the <em>runtime</em> |
| version of all this plug-in information. That is, how these declarative structures |
| are loaded, represented and used when the runtime is active.</p> |
| <p>The Eclipse runtime has two main elements; the OSGi framework and the Eclipse |
| runtime proper. The framework manages the set of bundles installed, their interdependencies |
| as well as all details of classloading and lifecycle. The runtime on the other |
| hand supports a registry of extensions and extension points as well as various |
| utility classes and mechanisms.</p> |
| <h3>OSGi framework</h3> |
| The Eclipse runtime is based on an implementation of an extended R3.0 OSGi framework |
| specification. The framework is responsible for managing plug-in dependencies, |
| file systems and class loading. The framework is |
| <h4>Bundles</h4> |
| Bundles are the OSGi framework unit of modularity. E |
| <h4>Plug-in Classloading</h4> |
| <p>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 <strong><code>code</code></strong> vs. a <strong><code>resource</code></strong> |
| library. Resource libraries are loaded by a resource loader and do not figure |
| into the strict classloading model.</p> |
| <p>Classloading in Eclipse follows the P-S-P model. That is, Parent-Self-Prerequisites. |
| </p> |
| <dl> |
| <dl> |
| <dt><b>Parent</b> </dt> |
| <dd>Each plug-in classloader has the Eclipse boot plug-in's classloader as |
| its parent. The boot plug-in 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.</dd> |
| <dt><b>Self</b></dt> |
| <dd>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 (in indeterminant order). Libraries from the same manifest |
| appear on the class path in the same order in which they were declared.</dd> |
| <dt><b>Prerequisites</b></dt> |
| <dd>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 (<code>org.eclipse.core.runtime</code>). |
| All plug-ins automatically have the Eclipse runtime plug-in (<code>org.eclipse.core.runtime</code>) |
| added to their prerequisite list as the first prerequisite. All imports |
| of the runtime plug-in are ignored. |
| <p> 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.</p> |
| </dd> |
| </dl> |
| </dl> |
| <h4>Plug-in Data</h4> |
| <p>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 <strong><code>plugins</code></strong> 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 |
| <code>plugin.xml</code> or <strong><code>fragment.xml</code></strong> file, |
| there may be any number of folders under the plug-in's root folder.</p> |
| <p>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.</p> |
| <dl> |
| <dl> |
| <dt><b>os</b></dt> |
| <dd>The operating system on which Eclipse is currently running (e.g., win32, |
| linux, solaris)</dd> |
| <dt><b>ws</b></dt> |
| <dd>The window system being used for the Eclipse UI (e.g., win32, motif, gtk)</dd> |
| <dt><b>arch</b></dt> |
| <dd>The type of processor in the machine (e.g., x86, ppc, sparc)</dd> |
| <dt><b>nl</b></dt> |
| <dd>The current locale (e.g., en_CA, jp_JP)</dd> |
| </dl> |
| </dl> |
| <p>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<em> |
| </em><strong><code>$ws$/<library name></code></strong> 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 <code>org.eclipse.swt</code> |
| plug-in uses this mechanism as follows:</p> |
| <blockquote> |
| <pre> <runtime> |
| <library name="$ws$/swt.jar"> |
| <export name="*"/> |
| </library> |
| </runtime> |
| </pre> |
| </blockquote> |
| <p>The SWT plug-in has a series of directories of the form <code>ws/<windowing |
| system>/</code>(e.g., <code>ws/win32</code>, <code>ws/gtk</code>, <code>ws/motif</code>). |
| Each of these directories contains a different version of <code>swt.jar</code>. |
| If you are working in an Eclipse environment in a win32 windowing system, the |
| library name <code>$ws$/swt.jar</code> will match <code>ws/win32/swt.jar</code>. |
| Note that in practice any given Eclipse install will have only one <code>swt.jar</code> |
| (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.</p> |
| <h4>Plug-in Activation</h4> |
| <p>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.</p> |
| <p>Many things can happen without activating a plug-in. In particular, </p> |
| <ul> |
| <li>resources can be loaded (either from a resource or code library) </li> |
| <li>plug-in classloaders can ask other classloaders to load classes. </li> |
| <li>extensions and extension points can be examined without having to activate |
| the plug-in that contains the extension. </li> |
| </ul> |
| <p>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.</p> |
| <h4> </h4> |
| <h2></h2> |
| <h3>Eclipse runtime</h3> |
| <h4>Extension registry</h4> |
| <p>As plug-ins and fragments are added to the framework and RESOLVED bundle events |
| are broadcast, the Eclipse runtime looks for <tt>plugin.xml</tt> files in the |
| root of the plug-in's file structure. If one is found, it is used to build the |
| <i>extension registry</i>. Each discovered file is parsed by the runtime which |
| then validates the declared extension and extension point entries (all #REQUIRED |
| fields must be present) and the entries to the registry. Invalid entries are |
| skipped and noted in the platform's log (typically under the <code><instance>/.metadata</code> |
| directory). As entries are added to the registry they are crosslinked with existing |
| entries. The resulting extension registry is available via the <code>org.eclipse.core.runtime</code> |
| plug-in's API. </p> |
| <p>Any new crosslinking between extensions and extension points are reported to |
| interested parties via IRegistryChangedEvents. Plug-ins can register extension |
| change listeners (IExtensionChangeListener) with the runtime using </p> |
| <pre> IRegistryChangeListener listener = new IRegistryChangeListener() ...; |
| Platform.getExtensionRegistry().addRegistryChangeListener(listener);</pre> |
| <p>Listeners receive change events which detail the changes in the set of extensions |
| present in a particular extension point. These events do not detail the addition |
| or removal of extensions or extension points independent of linkage activity. |
| Parties interested in monitoring this level of activity should register a BundleListener |
| with the framework and listen for BundleEvent.RESOLVED and BundleEvent.UNRESOLVED |
| events. When notified of such an event, the listener can query the extension |
| registry to discover the extensions and extension points related to the changed |
| bundle. </p> |
| <p> </p> |
| <p>Dynamic Plug-ins</p> |
| <p><XXX how to be dynamic></p> |
| <h4>Dynamic Plug-ins</h4> |
| <h2>Summary</h2> |
| <p>This article has set the stage for plug-ins: defining what they are, why they |
| are important and concepts related to them. The appendices give a more formal |
| definition of the XML used to define plug-ins, fragments, extension points, |
| etc. A companion article, "How Does the Platform Tick?" builds on |
| the concepts discussed here and gives a more detailed look into how plug-ins |
| work. </p> |
| <p>The following appendices are included for easy reference and are up-to-date |
| as of the time of the writing of this document. The Platform Plug-in Developers |
| Guide contains the most up-to-date versions of these documents for each Eclipse |
| release.</p> |
| <p> </p> |
| <p> </p> |
| <h2>Advanced topics </h2> |
| <h3>Managing the Eclipse install</h3> |
| <h3>Locations (user, install, configuration, instance)</h3> |
| <h3>system properties</h3> |
| <h3>command line args</h3> |
| <h3>running from jars</h3> |
| <h3>configurators</h3> |
| <h3>start levels</h3> |
| <h3>Adaptors</h3> |
| <h3>the boot sequence</h3> |
| <h3>state and resolver</h3> |
| <h3>Filtering</h3> |
| <p>Each classpath element can be refined using a set of filters which are evaluated |
| at runtime to determine if the entry is applicable to the current execution |
| environment. The filters are specified using the LDAP filtering syntax with |
| multiple filters separated by semi-colons.</p> |
| <p>Bundle-Classpath: runonunix.jar; selection-filter = "(osname=unix)", |
| runoneverythingelse.jar; selection-filter = "(!(osname=unix))" </p> |
| <p></p> |
| <p> </p> |
| <h2>Appendix: DTD for plugin.xml</h2> |
| <div class=Section1> |
| <pre><?xml encoding="US-ASCII"?> |
| <!ELEMENT plugin (extension-point*, extension*)> |
| |
| <!ELEMENT extension-point EMPTY> |
| |
| <!ATTLIST extension-point |
| name CDATA #REQUIRED |
| id CDATA #REQUIRED |
| schema CDATA #IMPLIED |
| > |
| |
| <!ELEMENT extension ANY> |
| |
| <!ATTLIST extension |
| point CDATA #REQUIRED |
| name CDATA #IMPLIED |
| id CDATA #IMPLIED |
| ></pre> |
| <p><a href="file:///D|/equinox/prototype/plugins/hglegal.htm"><img src="file:///D|/equinox/ngibmcpy.gif" alt="Copyright IBM Corporation and others 2000, 2003." border="0" width="250" height="12"></a></p> |
| </div> |
| <h2>Appendix: Plugin.xml description</h2> |
| <div class=Section1> <XXX fill in the plugin.xml description> |
| <p><a href="file:///D|/equinox/prototype/plugins/hglegal.htm"><img src="file:///D|/equinox/ngibmcpy.gif" alt="Copyright IBM Corporation and others 2000, 2003." border="0" width="250" height="12"></a></p> |
| </div> |
| <p> </p> |
| |
| </body> |
| </html> |