Version 2.3
Copyright © 2008, 2009, 2010, 2011, 2012 Lars Vogel
12.06.2012
| Revision History | |||
|---|---|---|---|
| Revision 0.1 - 0.7 | 18.09.2008 | Lars Vogel |
Created article |
| Revision 0.8 - 2.3 | 05.04.2009 - 12.06.2012 | Lars Vogel |
bug fixed and enhancements |
Table of Contents
This tutorial assumes what you have basic understanding of development for the Eclipse platform. Please see Eclipse 4 RCP Tutorial or Eclipse Plug-in Tutorial if you need any basic information.
Eclipse provides the concept of extension points and extensions to allow functionality to be contributed to plug-ins by several other plug-ins.
Extensions and Extension points are defined via the
plugin.xml
file.
The following table describes the terminology.
Table 1. Extensions and extension points table
| Term | Description |
|---|---|
| Plug-in defines extension point | Allows other plug-ins to add functionality based on the contract defined by the extension point. The plug-in which defines the extension point is also responsible for evaluating the extensions. Therefore the defining plug-in typically contains coding to evaluate the extensions. |
| A plug-in provides an extension | This plug-in provides an extension (contribution) based on the contract defined by an existing extension point. Contributions can be code or data. |
The Eclipse plug-in development environment (PDE) provides a
structured editor for the
plugin.xml
file. If you have the PDE tooling installed, you can open this editor
via a
double-click on the
plugin.xml
file.
Select the
Extensions
tab to define
extensions
which are contributed by your plug-in.
Select the
Extension Points
tab to see the
extension points
which your plug-in defines.

Using the button you can add new extensions. Once you added an extension you typically right-click on its elements to add elements or attributes to the extensions.
Typically Eclipse plug-in developers contribute more extensions to existing extension points than writing new extension points.
The information about the available extension points and the
provided
extensions are stored in a class of type
IExtensionRegistry.
The
resolution of the
extension points and provided extensions happen
as
a
plug-in is in the
RESOLVED
lifecyle status as defined by the OSGi
specification.
In Eclipse 4 you can use the dependency injection mechanism to
get
the
IExtensionRegistry
class.
@Inject public void doSomething(IExtensionRegistry registry){ // Do someting registry.getConfigurationElementsFor("your.extension"); }
In Eclipse 3.x you could have queried for a certain extension via the following code.
// The following will read all existing extensions
// for the defined ID
Platform.getExtensionRegistry().
getConfigurationElementsFor("your.extension");
A plug-in which defines an extension point must do the following:
Define the extension point in the
plugin.xml
file
Write code to load the extensions to this extension point
Evaluate the contributed extensions and use this information to do something
Extension points are defined via an XML schema file which is
referred
to in the
plugin.xml
file. This XML schema file defines
the
details and the contract of the
extension point.
For example
the
following shows the relation to the
schema file in the
plugin.xml
file.
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.2"?> <plugin> <extension-point id="de.vogella.extensionpoint.greeters" name="Greeters" schema="schema/de.vogella.extensionpoint.greeters.exsd" /> </plugin>
If you define your class directly in the extension point you are
limited to classes which have a default constructor. To avoid this
restriction you can use extension factories to create the object
which
is then returned. To use a factory implement the interface
IExecutableExtensionFactory
in the class attribute of your
extension point definition. The factory
receives the configuration
elements and can construct the required
object.
In this tutorial we will create two plug-ins. The first one defines an extension point and the second one will contribute extensions.
You can include these plug-ins in your Eclipse application or you could even use them in the Eclipse IDE.
Create a new plug-in project called de.vogella.extensionpoint.definition. This example will not make contribution to the UI, select this option in the wizard. Also select "No" for the Would you like to create a rich client application? option. The option to create an Activator should be selected.

Open the
MANIFEST.MF
file and the
Extension Points
tab.
Press the
button.

On the following dialog enter "de.vogella.extensionpoint.definition.greeter" as ID and "Greeter" as name. The Extension Point Schema field will be automatically populated based on your input.

Press . The definition of the extension is generated and the schema editor opens. Switch to the Definition Tab.

We want to add attributes to the extension point. Click on the New Element button. Give the new element the name "client".

Select the "client" element and press
. Give the
new
element the name "class" and the type "java". Enter
de.vogella.extensionpoint.definition.IGreeter
as interface name

This interface is not yet defined. Press on the hyperlink called Implements to create it.
package de.vogella.extensionpoint.definition; public interface IGreeter { void greet(); }
Go back to your extension point definition and add a choice to the extension point. This defines how often the extension "client" can be provided by contributing plug-ins. We will set no restrictions (unbound).




Select the
MANIFEST.MF
file switch to the
Runtime
tab and
export
the
package which contains the
IGreeter
interface.

The plug-in which defines an extension point is typically also
responsible
for
reading and using the provided extensions.
It is up to
you
where in
your coding you do this. The
following shows the method for
the
evaluation. In Eclipse 4 the
IExtensionRegistry
can get injected via dependency injection
.
We are using the
ISafeRunnable
interface. This interface protects the plug-in which defines
the
extension point from malfunction extensions. If an
extension throws an
Exception, it will be caught by
ISafeRunnable
and
the remaining extensions will still get executed.
package de.vogella.extensionpoint.definition.handlers; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.e4.core.di.annotations.Execute; import de.vogella.extensionpoint.definition.IGreeter; public class EvaluateContributionsHandler { private static final String IGREETER_ID = "de.vogella.extensionpoint.definition.greeter"; @Execute public void execute(IExtensionRegistry registry) { evaluate(registry); } private void evaluate(IExtensionRegistry registry) { IConfigurationElement[] config = registry.getConfigurationElementsFor(IGREETER_ID); try { for (IConfigurationElement e : config) { System.out.println("Evaluating extension"); final Object o = e.createExecutableExtension("class"); if (o instanceof IGreeter) { executeExtension(o); } } } catch (CoreException ex) { System.out.println(ex.getMessage()); } } private void executeExtension(final Object o) { ISafeRunnable runnable = new ISafeRunnable() { @Override public void handleException(Throwable e) { System.out.println("Exception in client"); } @Override public void run() throws Exception { ((IGreeter) o).greet(); } }; SafeRunner.run(runnable); } }
Review the
.exsd
schema file and
the
reference to this file in the
plugin.xml
file.
Run your application. It should write "Starting" to the console. Your extension point is implemented. Other plug-ins can now contribute extensions.
Create a new headless plug-in. This plug-in should be called de.vogella.extensionpoint.contribution. It should not be an RCP application. Do not use a template to create it.
Select the
MANIFEST.MF
file
and the
Dependencies
tab. Add the
de.vogella.extensionpoint.definition
and
org.eclipse.core.runtime
plug-ins
as a dependency. Make sure
your plug-in has
the singleton flag
set.

Switch to the Extensions tab and select . Select your own extension point and press the Finish button.

Add a client to your extension point.

Create the
GreeterGerman
class
with the
following coding.

package de.vogella.extensionpoint.contribution; import de.vogella.extensionpoint.definition.IGreeter; public class GreeterGerman implements IGreeter { @Override public void greet() { System.out.println("Moin Jungs!"); } }
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
vogella Training Android and Eclipse Training from the vogella team
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system