blob: 4148867a022d77432c7a4e60c9cc61ba515250a4 [file] [log] [blame]
<!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>&nbsp;</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 &quot;new world&quot; 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> &lt;XXX example here&gt; </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 ( &#146;,&#146; path )*
path ::= &lt;path name of nested JAR file or directory with &quot;/&quot;-separated components&gt; | &#146;.&#146;</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, &quot;../../foo.jar&quot;
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>&lt;example here&gt;</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>&lt;XXX need picture here&gt;</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=&quot;true&quot;</pre>
</blockquote>
Finally, plug-in prerequisite elements can be made optional by adding the <code>optional=&quot;true&quot;</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=&quot;true&quot;</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>&lt;XXX expand this section with info from OSGi spec&gt;</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> &lt;extension-point name="Action Sets" id="actionSets"/&gt;</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 &lt;plugin&gt; which has no attributes. The snippet below shows an example
extension and extension point in a plugin.xml file.</p>
<blockquote>
<pre>&lt;plugin&gt;
&lt;extension
point=&quot;org.eclipse.ui.actionSets&quot;&gt;
&lt;actionSet
label=&quot;Example&quot;
visible=&quot;false&quot;
id=&quot;com.example.actions&quot;&gt;
&lt;action
id=&quot;com.example.action1&quot;
class=&quot;com.example.CoolAction&quot;
icon=&quot;icons/action1.gif&quot;
helpContextId=&quot;action1_context&quot;
label=&quot;Action1&quot;
&lt;/action&gt;
&lt;/actionSet&gt;
&lt;/extension&gt;
&lt;extension-point id=&quot;foo&quot; name=&quot;An Example&quot;/&gt;
&lt;/plugin&gt;</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$/&lt;library name&gt;</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> &lt;runtime&gt;
&lt;library name=&quot;$ws$/swt.jar&quot;&gt;
&lt;export name=&quot;*&quot;/&gt;
&lt;/library&gt;
&lt;/runtime&gt;
</pre>
</blockquote>
<p>The SWT plug-in has a series of directories of the form <code>ws/&lt;windowing
system&gt;/</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>&nbsp;</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>&lt;instance&gt;/.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>&nbsp;</p>
<p>Dynamic Plug-ins</p>
<p>&lt;XXX how to be dynamic&gt;</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, &quot;How Does the Platform Tick?&quot; 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>&nbsp;</p>
<p>&nbsp;</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 = &quot;(osname=unix)&quot;,
runoneverythingelse.jar; selection-filter = &quot;(!(osname=unix))&quot; </p>
<p></p>
<p>&nbsp; </p>
<h2>Appendix: DTD for plugin.xml</h2>
<div class=Section1>
<pre>&lt;?xml encoding=&quot;US-ASCII&quot;?&gt;
&lt;!ELEMENT plugin (extension-point*, extension*)&gt;
&lt;!ELEMENT extension-point EMPTY&gt;
&lt;!ATTLIST extension-point
name CDATA #REQUIRED
id CDATA #REQUIRED
schema CDATA #IMPLIED
&gt;
&lt;!ELEMENT extension ANY&gt;
&lt;!ATTLIST extension
point CDATA #REQUIRED
name CDATA #IMPLIED
id CDATA #IMPLIED
&gt;</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> &lt;XXX fill in the plugin.xml description&gt;
<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>&nbsp;</p>
</body>
</html>