| Java, Eclipse and Web programming Tutorials |
Version 1.0
Copyright © 2008 - 2009 Lars Vogel
20.04.2009
| Revision History | ||
|---|---|---|
| Revision 0.1 - 0.7 | 18.09.2008 | Lars Vogel |
| Created article | ||
| Revision 0.8 | 05.04.2009 | Lars Vogel |
| Added explanation Extension point vrs. Extension | ||
| Revision 0.9 | 19.04.2009 | Lars Vogel |
| Improved overview part | ||
| Revision 1.0 | 20.04.2009 | Lars Vogel |
| Introducted ISafeRunnable | ||
Table of Contents
Extension Points allow that functionality is contributed to a specific plugin which defines this extension point. The functionality can then be contributed by any plugin which defines an extension for the defined extension point.
So an overview:
Extension Point: Defines the possibility to add functionality
Extension: Uses the extension point to provide functionality, also known as contributions
Functionality can be code but also non-code related contributions, e.g. help context.
The plugin which defines extension points defines a contract for other plugins how these plugins could provide functionality via this extension point.
The plugin which defines the extension point is also responsible for evaluating the contributions.
To define a extension point you perform the following:
Design the extension point
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 the file plugin.xml. For example the following show the extension point which will defined in the following example.
<?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"/>
<extension
id="application"
point="org.eclipse.core.runtime.applications">
<application>
<run
class="de.vogella.extensionprovider.simple.Application">
</run>
</application>
</extension>
</plugin>
The extension point refers to an XML Schema which defines the details of the extension point.
Eclipse provides for both files a powerful editor which the following example will demonstrate.
We will create a simple example where our RCP application allows to says "Hello" in different languages via Plugins.
Create a new project "de.vogella.extensionprovider.simple" (see See Creating Eclipse RCP application on how to create a new RCP project). This example will not make contribution to the UI, select this setting in the wizard. Use the "Headless Hello RCP" as a template. The plugin should get an Activator.
Select the MANIFEST.MF and select the tab "Extension Points". Press Add

Give the new extension point the ID "de.vogella.extensionpoint.greeters" and the name "Greeters". Leave the schema as it is generated.

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

The definition for extension is already created and should not get changed. Click on the "New Element" button. Give the new element the name client.

Select your new element and press "New Attribute". Give the new element the name class and the type java. The interface should be "de.vogella.extensionprovider.IGreeter". Press on Implements to create this interface.


Create the following coding.
package de.vogella.extensionprovider;
public interface IGreeter {
void greet();
}
In your plugin.xml switch to the runtime tab and export the package which contains IGreeter.

Now add a choice to the extension point.



In your application you have to read all registered extensions. It is basically up to you where in your coding you do this. The following will do it directly in Application.java in the start method but you can decide to do it somewhere else.
Please note that 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.extensionprovider.simple;
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;
import de.vogella.extensionprovider.IGreeter;
/**
* This class controls all aspects of the application's execution
*/
public class Application implements IApplication {
// This must be the ID from your extension point
private static final String IGREETER_ID = "de.vogella.extensionpoint.greeters";
/*
* (non-Javadoc)
*
* @seeorg.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
* IApplicationContext)
*/
public Object start(IApplicationContext context) throws Exception {
System.out.println("Hello RCP World!");
runGreeterExtension();
return IApplication.EXIT_OK;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.equinox.app.IApplication#stop()
*/
public void stop() {
// nothing to do
}
private void runGreeterExtension() {
try {
IConfigurationElement[] config = Platform.getExtensionRegistry()
.getConfigurationElementsFor(IGREETER_ID);
for (IConfigurationElement e : config) {
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 (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Run your application. It should write "Hello RCP World!" to the console. You application is finished and it ready to get extended by other plugins.
Create a new headless plugin "de.vogella.extensionusage.simple". This plugin should not be an RCP application. Use no template to create it.
Select Manifest.MF and the tab Dependencies. Add "de.vogella.extensionprovider.simple" as a dependency. Switch to the extension tab and select "Add". Select your extension point and press Finish.
Add a client to your extension point.

Create the class de.vogella.extensionusage.simple.GreeterGerman with the following coding.

package de.vogella.extensionusage.simple;
import de.vogella.extensionprovider.IGreeter;
public class GreeterGerman implements IGreeter {
public GreeterGerman() {
}
@Override
public void greet() {
System.out.println("Moin");
}
}
Thank you for practicing with this tutorial.
Please note that I maintain this website in my private time. If you like the information I'm providing please help me by donating.For questions and discussion around this article please use the www.vogella.de Google Group. Also if you note an error in this article please post the error and if possible the correction to the Group.
I believe the following is a very good guideline for asking questions in general and also for the Google group How To Ask Questions The Smart Way.
http://www.vogella.de/code/codeeclipse.html Source Code of Examples