vogella.de

Follow me on twitter
About Lars Vogel
Flattr this

Eclipse Extension Points and Extensions - Tutorial

Lars Vogel

Version 1.4

16.08.2010

Revision History
Revision 0.1 - 0.718.09.2008Lars Vogel
Created article
Revision 0.8 - 1.4 05.04.2009 - 16.08.2010Lars Vogel
bug fixed and enhancements

Eclipse Extension Points

This article describes the definition and usage of the Eclipse Extension Points. The article is based on Eclipse 3.6 (Helios) and Java 1.6.


Table of Contents

1. Eclipse Extensions
1.1. What are Extension Points and Extensions?
1.2. Analysis
1.3. Process of creating an extension point
1.4. Tooling
2. Hello World extension point
2.1. Creating the extension provider
2.2. Evaluating the registered extensions
2.3. Providing an extension
2.4. Run the example
3. Extension Factories
4. Thank you
5. Questions and Discussion
6. Links and Literature
6.1. Source Code
6.2. vogella Resources

1. Eclipse Extensions

Tip

The following assumes that you are familiar with Eclipse RCP or Eclipse Plugin Development .

1.1. What are Extension Points and Extensions?

Eclipse provides the concept of "extension points" and "extensions" to facilitate that functionality can be contributed to plugins by other plugins. Plugins which define extension points open themself up for other plugins. A extension points defines a contact how other plugins can contribute. The plugin which defines the extension point is also responsible for evaluating the contributions. Therefore the plugin which defines an extension point both defines the extension point and has some coding to evaluate contributions of other plugins.

A plugin which defines an "extension" contributes to the defined "extension point". The contributed can be done by any plugin. Contributions can be code but also data contributions, e.g. help context. Extensions to an extension points are defined in the plugins via the file "plugin.xml" using XML.

The information of the available extension points and the provided extensions are stored in the Eclipse "Extension Registry". The resolution of the extension points and provided extension happen as a plugin is the lifecyle status "resolved". This lifecycle status is defined by the OSGI runtime, Equinox, which is used by Eclipse.

To summarize:
  • A plugin defines an Extension Point: this plugin allow other plugins to add functionality based on the defined contact by the extension point

  • A plugin provides an Extension: This plugin added a contribution to an existing extension point.

1.2. Analysis

The concept of extension points allows to contribute functionality to plugins without changing the existing code of the plugin. This is a powerful concept as it allows to developed functionality decoupled. The extension mechanism is declarative, therefore the dependencies can be evaluated without loading any code. This allows lasy loading of plugins and therefore scales very well with lots of plugins.

1.3. Process of creating an extension point

A plugin which defines an extension points must do the following.

  • Define the extension point in the MANIFEST.MF

  • Write code to load the extensions to this extension point

  • Load / Call the extensions when needed

Extension points are defined via an XML schema file which is referred to in the the file plugin.xml. 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 file "plugin.xml".

				
<?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>
			

1.4. Tooling

Eclipse PDE provides powerful tooling to work with extension points. The usage of the PDE tooling will be demonstrated in the following example.

2. Hello World extension point

2.1. Creating the extension provider

We will create an Eclipse RCP application which allows to be extended by other plugins via an extension point. The application will be a simple console application without UI.

Create a new project "de.vogella.extensionpoint.definition" (see Creating Eclipse RCP application for details). This example will not make contribution to the UI, select this setting in the wizard. Use the "Headless Hello RCP" as a template. The option of the activator should be active.

Select the file "MANIFEST.MF" and the tab "Extension Points". Press Add.

Use the ID "de.vogella.extensionpoint.definition.greeter" and the name "Greeter". The schema name will be generated for you.

You should now in the schema editor. Switch to the "Definition" Tab.

The definition for extension is already created. Adds attributes to the extension point. Click therefore on the "New Element" button. Give the new element the name "client".

Select the "client" element and press "New Attribute". Give the new element the name class and the type java. The interface should be "de.vogella.extensionpoint.definition.IGreeter".

Press on the hyperlink "Implements" to create this interface "IGreeter".

				
package de.vogella.extensionpoint.definition;

public interface IGreeter {
	void greet();
}

			

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

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 plugins. We will set no restrictions (unbound).

2.2. Evaluating the registered extensions

The plugin which defines an extension point is also responisble for reading and using the provided extensions. It is up to you where in your coding you do this. The following will do it directly in Application.java.

We are using ISafeRunnable. This interface allows to protect yourself from malfunction extensions. If the extension throws an exception it will be caught and the remaining extensions will still get executed.

				
package de.vogella.extensionpoint.definition;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;

/**
 * This class controls all aspects of the application's execution
 */
public class Application implements IApplication {

	// This is the ID from your extension point
	private static final String IGREETER_ID = "de.vogella.extensionpoint.definition.greeter";

	public Object start(IApplicationContext context) throws Exception {
		System.out.println("Starting");
		runGreeterExtension();

		return IApplication.EXIT_OK;
	}

	public void stop() {
		//nothing to do
	}

	private void runGreeterExtension() {
		IConfigurationElement[] config = Platform.getExtensionRegistry()
				.getConfigurationElementsFor(IGREETER_ID);
		try {
			for (IConfigurationElement e : config) {
				System.out.println("Evaluating extension");
				final Object o = e.createExecutableExtension("class");
				if (o instanceof IGreeter) {
					ISafeRunnable runnable = new ISafeRunnable() {
						@Override
						public void handleException(Throwable exception) {
							System.out.println("Exception in client");
						}

						@Override
						public void run() throws Exception {
							((IGreeter) o).greet();
						}
					};
					SafeRunner.run(runnable);
				}
			}
		} catch (CoreException ex) {
			System.out.println(ex.getMessage());
		}
	}

}

			

Have a look at the generated file "schema/de.vogella.extensionpoint.definition.greeter.exsd" and the reference to this file in "plugin.xml".

Run your application. It should write "Starting" to the console. You application is finished and it ready to get extended by other plugins!

2.3. Providing an extension

Create a new headless plugin "de.vogella.extensionpoint.contribution". This plugin should not be an RCP application. Use no template to create it.

Select "MANIFEST.MF" and the tab "Dependencies". Add "de.vogella.extensionpoint.definition" and "org.eclipse.core.runtime" as a dependency. Make sure your plugin has the singleton flag set.

Switch to the "Extensions" tab and select "Add". Select your extension point and press Finish.

Add a client to your extension point.

Create the class "de.vogella.extensionpoint.contribution.GreeterGerman" 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!");
	}

}

			

2.4. Run the example

Create a launch configuration which contains both plugins and run your application. It should print the grettings from the contributing plugin to the console.

3. Extension Factories

If you define your class directly in the extension point you are limited to classes with 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.

4. Thank you

Thank you for practicing with this tutorial.

I maintain this tutorial in my private time. If you like the information please help me by using flattr or donating or by recommending this tutorial to other people.

Flattr this

5. Questions and Discussion

Before posting questions, please see the vogella FAQ . If you have questions or find an error in this article please use the www.vogella.de Google Group . I have created a short list how to create good questions which might also help you. .

6. Links and Literature

6.1. Source Code

Source Code of Examples