1. Prerequisites for this tutorial

This tutorial assumes that you have basic understanding of development for the Eclipse platform. Please see Eclipse RCP Tutorial or Eclipse plug-in Tutorial if you need any basic information.

2. Extensions and Extension Points

Eclipse provides the concept of extensions to contribute functionality to a specific type of API. A plug-in defines this type of API through an extension point. One or more plug-ins can contribute extensions to it.

These extensions and extension points are defined in the plugin.xml file.

The following graphic illustrates this concept, and the table below describes the terminology.

Extensions and extension points concept
Table 1. Extensions and Extension Points
Term Description

Plug-in defines extension point

The plug-in defines a contract (API) by declaring an extension point that allows other plug-ins to add contributions (extensions). It is responsible for evaluating the extensions and typically contains the necessary code to do so.

Plug-in provides an extension

This plug-in provides an extension (contribution) based on the contract defined by an existing extension point. Contributions can consist of code or data.

3. Creating an extension point

A plug-in declares an extension point in its plugin.xml file. Use the Extension Points tab of the editor for the definition.

An XML schema file (.exsd) defines the details and the contract of the extension point. The plugin.xml file refers to this schema file, as the following example shows.

<?xml version="1.0" encoding="utf-8"?>
<?eclipse version="3.2"?>
<plugin>
    <extension-point id="com.vogella.extensionpoint.definition.greeter"
        name="Greeter"
        schema="schema/com.vogella.extensionpoint.definition.greeter.exsd" />
</plugin>

The plug-in typically contains code to evaluate the extensions for this extension point.

4. Adding extensions to extension points

The Eclipse IDE provides an editor for the plugin.xml file. It is the same editor that is used for the MANIFEST.MF file.

Select the Extensions tab in this editor to create new extensions. On the Extension Points tab you can define new extension points.

Extensions defined by plug-in

Use the Add…​ button to add a new extension. Right-click on an extension to add elements or attributes.

5. Accessing extensions

The IExtensionRegistry stores the information about all available extension points and the provided extensions. The Eclipse platform reads them once the plug-in is in the RESOLVED lifecycle state, as defined by the OSGi specification. Via this registry you can access all extensions in your running application.

You can get it via dependency injection.

@Inject 
public void doSomething(IExtensionRegistry registry){
    // do something
    registry.getConfigurationElementsFor("yourextension");
}

For objects not created by dependency injection, you can use the static methods of the Platform class instead.

Platform.getExtensionRegistry().getConfigurationElementsFor("yourextension");

6. Extension Factories

If you create the class via the createExecutableExtension method of the IConfigurationElement class, it must have a default constructor. To avoid this restriction, use an extension factory.

To use a factory, implement the IExecutableExtensionFactory interface and reference it in the class attribute of your extension. If the factory also implements IExecutableExtension, it receives the configuration element and can use it to construct the required object.

7. Optional exercise: Create and evaluate an extension point

In this exercise, you create two new plug-ins. The first one contains an extension point. The second plug-in contributes an extension to the new extension point.

7.1. Creating a plug-in for the extension point definition

Create a new simple plug-in project called com.vogella.extensionpoint.definition.

7.2. Create an extension point

Open the MANIFEST.MF file or the plugin.xml file and select the Extension Points tab.

Extension Points tab of the manifest editor

Press the Add…​ button.

Enter com.vogella.extensionpoint.definition.greeter as Extension Point ID and Greeter as Extension Point Name in the dialog. The Extension Point Schema field is automatically populated based on your input.

Define Extension Point

Press the Finish button. The extension point is added to the plugin.xml file and the schema editor opens. Switch to the Definition tab.

Extension Point Schema Editor

7.3. Add attributes to the extension point

Start by clicking the New Element button. Give the new element the name client.

Add Elements to Extension

Select the client element and press New Attribute. Give the new attribute the name class and the type java. Enter com.vogella.extensionpoint.definition.IGreeter as interface name.

Add Attribute to Extension

This interface does not exist yet. Click the Implements hyperlink to create it and use the following code.

package com.vogella.extensionpoint.definition;

public interface IGreeter {
    void greet();
}

Go back to your extension point definition and add a choice to it. Select the extension entry, right-click on it and select New  Choice. The choice defines how often contributing plug-ins can provide the client element. Set it to unbounded (no restrictions).

Context menu to add a Choice to the extension element
Choice compositor details with the Unbounded option set
Context menu to add the client element to the Choice
Schema editor with the client reference below the Choice

7.4. Export the package

Open the MANIFEST.MF file, switch to the Runtime tab and export the package that contains the IGreeter interface.

Export IGreeter package

7.5. Add dependencies

Add the following dependencies via the MANIFEST.MF file of your new plug-in:

  • org.eclipse.core.runtime

  • org.eclipse.e4.core.di

7.6. Evaluating the registered extensions

The defining plug-in evaluates the existing extensions. Create the following handler class for this.

package com.vogella.extensionpoint.definition;

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;

public class EvaluateContributionsHandler {
    private static final String IGREETER_ID = 
            "com.vogella.extensionpoint.definition.greeter";
    @Execute
    public void execute(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);
    }
}

The executeExtension method uses ISafeRunnable to protect the defining plug-in from malfunctioning extensions. If the greet method of an extension throws an exception, SafeRunner catches it and the remaining extensions are still executed.

Review the .exsd schema file and the reference to this file in the plugin.xml file.

7.7. Create a menu entry and add it to the product

Add a dependency to the com.vogella.extensionpoint.definition plug-in in the MANIFEST.MF file of your application plug-in.

Afterwards, create a new menu entry called Evaluate extensions and define a command and handler for this menu entry. In the handler, reference the EvaluateContributionsHandler class.

A better approach is to add the menu entry via a model fragment or a model processor, which is left as an additional exercise.

7.8. Providing an extension

Create a new simple plug-in called com.vogella.extensionpoint.contribution.

Open the MANIFEST.MF editor of this new plug-in and select the Dependencies tab.

Add the com.vogella.extensionpoint.definition and org.eclipse.core.runtime plug-ins as dependencies. Ensure that the This plug-in is a singleton flag is enabled on the Overview tab of your MANIFEST.MF file.

Overview tab of the contribution plug-in with the singleton option

Switch to the Extensions tab and select Add…​. Select your custom extension point and press the Finish button.

New Extension wizard with the custom Greeter extension point selected

Add a client element to your extension point via right-click.

Context menu to add a client element to the extension
Extension Element Details with the class value of the client element

Create the GreeterGerman class with the following code.

package com.vogella.extensionpoint.contribution;

import com.vogella.extensionpoint.definition.IGreeter;

public class GreeterGerman implements IGreeter {

    @Override
    public void greet() {
        System.out.println("Hallo!");
    }
}

7.9. Update product

Add the new plug-ins to your product (via your feature configuration).

  • com.vogella.extensionpoint.contribution

  • com.vogella.extensionpoint.definition

7.10. Validate

Start your application via the product configuration file to update the plug-ins in the run configuration.

In your running application select your new menu entry. The handler class writes the output of your extensions to the Console view of your Eclipse IDE.

Home Tutorials Training Consulting Books Company Contact us


Get more...