Developing Eclipse plug-ins

How to create, debug, and install your plug-in

In this article, author David Gallardo shows you how to create Eclipse plug-ins using the Plug-in Development Environment's code generation wizard. You'll learn how to run and debug the plug-in in the run-time workbench and install the completed plug-in in Eclipse. He also examines issues relating to packaging plug-ins -- including maintaining version information, upgrading functionality in the form of plug-in fragments, and combining plug-ins to create complete features.

David Gallardo (david@gallardo.org), Software consultant

David Gallardo is an independent software consultant and author specializing in software internationalization, Java Web applications, and database development. He has been a professional software engineer for over fifteen years and has experience with many operating systems, programming languages, and network protocols. His recent experience includes leading database and internationalization development at a business-to-business e-commerce company, TradeAccess, Inc. Prior to that, he was a senior engineer in the International Product Development group at Lotus Development Corporation where he contributed to the development of a cross-platform library providing Unicode and international language support for Lotus products including Domino. You can reach David at david@gallardo.org.



01 December 2002

Also available in Chinese Russian Japanese Portuguese

A plug-in-based architecture

The Eclipse Platform, a development framework donated to the open source community by IBM®, is notable not because of the sum of money IBM is said to have spent developing it -- $40 million -- but rather because of what they have to show for the expenditure: a mature, well-designed, and extensible architecture. What is valuable about Eclipse is that it provides an open source platform for creating an extensible integrated development environment (IDE). This platform allows anyone to build tools that integrate seamlessly with the environment and other tools.

The key to the seamless integration of tools with Eclipse is the plug-in. With the exception of a small runtime kernel, everything in Eclipse is a plug-in. This means that a plug-in you develop integrates with Eclipse in exactly the same way as other plug-ins; in this respect, all features are created equal.

Some plug-ins are more equal than others, however. The Workbench and the Workspace are two indispensable plug-ins of the Eclipse Platform — they provide the extension points used by most of the plug-ins, as shown in Figure 1. A plug-in requires an extension point to plug into in order to function.

Figure 1. The Eclipse Workbench and Workspace: Essential plug-in support
Eclipse Workbench

The Workbench component contains extension points that, for example, allow your plug-in to extend the Eclipse user interface with menu selections and toolbar buttons, to request notification of different types of events, and to create new views. The Workspace component contains extension points that allow you to interact with resources, including projects and files.

The Workbench and the Workspace are not the only Eclipse components that can be extended by other plug-ins, of course. In addition, there is a Debug component that will let your plug-in launch a program, interact with the running program, and handle errors -- everything necessary to build a debugger. While necessary for certain types of applications, the Debug component is not needed by most applications.

There is also a Team component that allows Eclipse resources to interact with version control systems (VCS), but unless you are building an Eclipse client for a VCS, the Team component, like the Debug component, will not have its functionality extended or enhanced.

Finally, there is a Help component available to allow you to provide online documentation and context-sensitive help for your application. There is no denying that help documentation is an essential part of a professional application, but it is not essential to a plug-in's functionality.

The extension points that each of the above components provide are documented in the Eclipse Platform Help, in the reference section of the Platform Plug-in Developer guide. A quick glance, particularly at the Workbench section of the API reference is initially daunting. Rather than diving into the details of the many available extension points, we'll just dip our feet in by taking a look at a simple plug-in and its components.


A gentle introduction to plug-ins

The easiest way to create a plug-in is to use the Plug-in Development Environment (PDE). The PDE, along with the Java™ Development Tooling (JDT) IDE, comes as a standard extension to Eclipse. The PDE provides wizards to help create plug-ins, including the "Hello World" example we will examine here.

From the Eclipse menu, select File > New > Other (or press Ctrl+N), then select the Plug-in Development wizard on the left side of the Select dialog. On the right side of the Select dialog, choose Plug-in Project. Press Next. On the next screen, enter a project name; I used com.example.hello. Press Next again. On the next screen, notice that the plug-in ID corresponds to the project name. Using the project name as the plug-in ID minimizes the chances that this plug-in will conflict with the name of another plug-in. Click Next again. The next screen gives you the choice of manually creating the initial plug-in code or running a code-generation wizard. Leave the code-generation wizard default, select Hello World and click Next, as shown in Figure 2.

Figure 2. Selecting the Hello World code-generation wizard
New plug-in

The next screen requests additional information. Notice the information on this screen: it includes the plug-in name, version number, provider name, and class name. These are important pieces of information about our plug-in, as we will see later. You can accept the defaults provided by the wizard. Click Next. On the next screen, accept the defaults for package name, class name, and message text. Leave the checkbox marked "Add the action set to the resource perspective," then click Finish.

If you are notified that the wizard needs to enable certain other plug-ins in order to complete, click OK.

After a while, the wizard will complete and you will have a new project named com.example.hello in your workspace, as shown in Figure 3.

Figure 3. The PDE Perspective: Welcome to Hello Plug-in
PDE perspective

On the left of the workbench, in the Package Explorer, is an overview of some of the things the wizard created. Most of the items are not very interesting. There are a number of .jar files included in the project classpath (these include the Eclipse classes required by the plug-in and the Java run-time), an icons folder containing a graphic for a toolbar button, and a build.properties file containing variables used by an automated build script.

The most interesting things here are the src folder, which contains the source code for our plug-in and the plugin.xml file — the plug-in's manifest file. We will take a look at plugin.xml first.


The plug-in manifest file

The plug-in manifest file, plugin.xml, contains descriptive information that will be used by Eclipse to integrate the plug-in into the framework. By default, plugin.xml is opened in the manifest editor area when the plug-in is first created. Tabs at the bottom of the editor allow you to select different sets of information about the plug-in. The Welcome tab displays the message "Welcome to Hello Plug-In" and briefly discusses the templates used and tips on using Eclipse to implement the plug-in. Selecting the Source tab will let you see the complete source of the plugin.xml file.

Let's take a look at the different parts of the plug-in manifest file. First is general information about the plug-in, including its name, version number, the name of the class file that implements it, and the JAR file name.

Listing 1. Plug-in manifest file — General information
<?xmlversion="1.0" encoding="UTF-8"?>
<plugin
   id="com.example.hello"
   name="Hello Plug-in"
   version="1.0.0"
   provider-name="EXAMPLE"
   class="com.example.hello.HelloPlugin">

   <runtime>
      <library name="hello.jar"/>
   </runtime>

Next, the plug-ins required by our plug-in are listed.

Listing 2. Plug-in manifest file — Required plug-ins
   <requires>  
      <import plugin="org.eclipse.core.resources"/>
      <import plugin="org.eclipse.ui"/>
   </requires>

The first plug-in listed, org.eclipse.core.resources, is the workspace plug-in, but it is not actually needed by our plug-in. The second plug-in, org.eclipse.ui, is the workbench. We need the workbench plug-in because we will be extending two of its extension points as indicated by the extension tags that follow.

The first extension tag has the point attribute org.eclipse.ui.actionSets. An action set is a group of contributions that a plug-in adds to the workbench user interface — that is, menus, menu items, and toolbars. An action set groups contributions so that a user can more easily manage them. For example, our Hello plug-in's menu and toolbar items will appear in the Resource Perspective because of the choice we made when we ran the code-generation wizard. The user can change this using the Window > Customize Perspective menu option to remove "Sample Action Set" from the items to be displayed in the Resource Perspective.

Figure 4. Customizing the Resource Perspective
Resource Perspective

The action set contains two tags: a menu tag that describes where and how our item should appear in the workbench menu, and an action tag that describes what it should do — in particular, the action tag identifies the class that performs the action. Note that this class is different from the plug-in class listed above.

Listing 3. Action set
   <extension
         point="org.eclipse.ui.actionSets">
      <actionSet
            label="Sample Action Set"
            visible="true"
            id="com.example.hello.actionSet">
         <menu
               label="Sample &Menu"
               id="sampleMenu">
            <separator
                  name="sampleGroup">
            </separator>
         </menu>
         <action 
               label="&Sample Action"
               icon="icons/sample.gif"
               class="com.example.hello.actions.SampleAction"
               tooltip="Hello, Eclipse world"
               menubarPath="sampleMenu/sampleGroup"
               toolbarPath="sampleGroup"
               id="com.example.hello.actions.SampleAction">
         </action>
      </actionSet>
   </extension>

The purpose of many of the menu and action attributes is fairly obvious — for example, providing the tooltip text and identifying the graphic for the toolbar item. Also notice the menubarPath in the action tag: This attribute identifies which menu item defined in the menu tag invokes the action defined in the action tag. For more detailed information about this and other workbench extension points, refer to the Platform Plug-in Developer Guide, particularly the "Plugging into the workbench" chapter (the guide is available from the help menu in Eclipse).

The second extension tag was generated as a result of our electing to have our plug-in added to the Resource Perspective. This tag causes our plug-in to be added to the Resource Perspective when Eclipse first starts and loads our plug-in.

Listing 4. Extension tag
   <extension  
         point="org.eclipse.ui.perspectiveExtensions">
      <perspectiveExtension
            targetID="org.eclipse.ui.resourcePerspective">
         <actionSet
               id="com.example.hello.actionSet">
         </actionSet>
      </perspectiveExtension>
   </extension>
</plugin>

If this last extension had been omitted, the user would need to add the plug-in to the Resource (or other) Perspective using Window > Customize Perspective.


The plug-in source code

The code-generation wizard generated two Java source files, which you can see by opening the src folder in the PDE package explorer. The first, HelloPlugin.java is the plug-in class, and extends the AbstractUIPlugin abstract class. HelloPlugin is responsible for managing the life cycle of the plug-in and, in a more extended application, would be responsible for maintaining such things as dialog box settings and user preferences. HelloPlugin doesn't do much.

Listing 5. HelloPlugin
packagecom.example.hello.actions;

import org.eclipse.ui.plugin.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.resources.*;
import java.util.*;

/**
 * The main plugin class to be used in the desktop.
 */
public class HelloPlugin extends AbstractUIPlugin {
      //The shared instance.
      private static HelloPlugin plugin;
      //Resource bundle.
      private ResourceBundle resourceBundle;
      
      /**
       * The constructor.
       */
      public HelloPlugin(IPluginDescriptor descriptor) {
            super(descriptor);
            plugin = this;
            try {
                  resourceBundle= ResourceBundle.getBundle(
                       "com.example.hello.HelloPluginResources");
            } catch (MissingResourceException x) {
                  resourceBundle = null;
            }
      }

      /**
       * Returns the shared instance.
       */
      public static HelloPlugin getDefault() {
            return plugin;
      }

      /**
       * Returns the workspace instance.
       */
      public static IWorkspace getWorkspace() {
            return ResourcesPlugin.getWorkspace();
      }

      /**
       * Returns the string from the plugin's resource bundle,
       * or 'key' if not found.
       */
      public static String getResourceString(String key) {
            ResourceBundle bundle= HelloPlugin.getDefault().getResourceBundle();
            try {
                  return bundle.getString(key);
            } catch (MissingResourceException e) {
                  return key;
            }
      }

      /**
      * Returns the plugin's resource bundle,
      */
      public ResourceBundle getResourceBundle() {
          return resourceBundle;
      }
}

The second source file, SampleAction.java, contains the class that performs the action specified in the action set in the manifest file. SampleAction implements the IWorkbenchWindowActionDelegate interface, which allows Eclipse to use a proxy for our plug-in so that Eclipse does not need to load the plug-in until absolutely necessary (this optimization works to minimize memory and performance problems when plug-ins are loaded). The IWorkbenchWindowActionDelegate interface methods allow our plug-in to interact with the proxy.

Listing 6. IWorkbenchWindowActionDelegate interface methods
package com.example.hello.actions;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.jface.dialogs.MessageDialog;

/**
 * Our sample action implements workbench action delegate.
 * The action proxy will be created by the workbench and
 * shown in the UI. When the user tries to use the action,
 * this delegate will be created and execution will be 
 * delegated to it.
 * @see IWorkbenchWindowActionDelegate
 */
public class SampleAction implements IWorkbenchWindowActionDelegate {
      private IWorkbenchWindow window;
      /**
       * The constructor.
       */
      public SampleAction() {
      }

      /**
       * The action has been activated. The argument of the
       * method represents the 'real' action sitting
       * in the workbench UI.
       * @see IWorkbenchWindowActionDelegate#run
       */
      public void run(IAction action) {
            MessageDialog.openInformation(
                  window.getShell(),
                  "Hello Plug-in",
                  "Hello, Eclipse world");
      }

      /**
       * Selection in the workbench has been changed. We 
       * can change the state of the 'real' action here
       * if we want, but this can only happen after 
       * the delegate has been created.
       * @see IWorkbenchWindowActionDelegate#selectionChanged
       */
      public void selectionChanged(IAction action, ISelection selection) {
      }

      /**
       * We can use this method to dispose of any system
       * resources we previously allocated.
       * @see IWorkbenchWindowActionDelegate#dispose
       */
      public void dispose() {
      }

      /**
       * We will cache window object in order to
       * be able to provide parent shell for the message dialog.
       * @see IWorkbenchWindowActionDelegate#init
       */
      public void init(IWorkbenchWindow window) {
            this.window = window;
      }
}

Running and debugging the plug-in

When developing a plug-in for Eclipse, it would be awkward to have to stop Eclipse and then restart it with the new plug-in in order to test and debug. Eclipse's PDE, thankfully, provides a self-hosted development environment that lets you run a plug-in without installation in a separate instance of the workbench.

To run the Hello plug-in, select Run > Run As > Runtime Workbench to start another instance of the Workbench with our plug-in's menu selection and toolbar added as shown in Figure 5.

Figure 5. The Hello plug-in running in the runtime workbench
Hello plug-in

We can activate the plug-in by clicking on the toolbar button or from the "Sample Menu" menu. Either method will bring up a box titled "Hello Plug-in" with the contents "Hello, Eclipse world" and an OK button to dismiss it.

We can debug a plug-in in a similar way, by selecting Run > Debug As > Runtime Workbench. This time, we can step through the source code, examine variables, etc., in the original workbench while the plug-in runs in the second workbench instance.

Once our plug-in is tested and ready for release, we will need to package it appropriately for installation in Eclipse.


Packaging the plug-in

Eclipse determines what plug-ins to load by looking in its plugins directory at startup. To install a plug-in, we need to create a subdirectory in the plugins directory and copy our program files and manifest files there. It's not necessary, but it is recommended that the directory name indicate the plug-in's ID, followed by an underscore and the version number. Suppose that Eclipse is installed in C:\eclipse; we might make a directory:

C:\eclipse\plugins\com.example.hello_1.0.0.

As is standard with Java applications, our program files need to be archived into a JAR file — our plug-in manifest file, you may remember contained this entry:

   <runtime> 
      <library name="hello.jar"/>
   </runtime>

To create the hello.jar file, we can export our plug-in files by highlighting the project name and selecting File > Export from the Eclipse menu. Select JAR file as the destination, click Next and browse to the directory we created for it. Next, we need to copy the plugin.xml file to this directory too. You can use the File > Export menu selection as well (but remember to choose File System as the destination).

This is all that is required to install the plug-in, but you will need to stop and restart Eclipse for the new plug-in to be recognized. You can find information about the installed plug-ins, including version number, by selecting "About Eclipse Platform" from the help menu. One of the buttons on the screen that appears will be Plug-in Details; scroll down the list to find the Hello plug-in and its version number.


Updating the plug-in version

The purpose of including the version number in the directory name is to allow multiple versions of a plug-in to co-exist on the same machine (only one is loaded at a time). We can see how this works by creating an updated version of the Hello plug-in: For example, change the version number in the plugin.xml file to "1.0.1" and change the text in SampleAction.java to "New and improved Hello, Eclipse world." Select Project > Rebuild All from the Eclipse menu. Next, export the project files as a JAR to a new plug-in directory — for example, com.example.hello_1.0.1. Copy the revised plugin.xml file to the same directory. When you stop and restart Eclipse, only the updated plug-in will be loaded.


Plug-in fragments and features

Eclipse is composed of plug-ins, but there are two other levels of components that are important to consider when developing plug-ins for Eclipse: plug-in fragments and features.

A plug-in fragment, as the name suggests, forms a part of a full-fledged plug-in — the target plug-in. The functionality provided by the fragment is merged with that of the target plug-in. A fragment can be used to localize a plug-in for different languages, to incrementally add features to an existing plug-in without the need for a full new release, or to provide platform-specific functionality. In many respects a fragment is identical to a plug-in. The main difference is that a fragment does not have a plug-in class — the fragment's life cycle is managed by its target plug-in. In addition, the fragment's manifest file, called fragment.xml, lists the target plug-in's ID and version number as well as the fragment's ID and version number.

A plug-in feature, on the other hand, does not include coding at all. In Eclipse architecture terminology, a feature is the packaging of a group of related plug-ins into an integral product. For example, the JDT is a feature made up of plug-ins like a Java editor, debugger, and console. A manifest file called feature.xml describes a feature archive. Among other things, this manifest file includes references to the plug-ins and other resources that the feature comprises, information on how the feature is to be updated, copyright information, and license information.

In Eclipse a primary feature sets the look and feel of the Eclipse Platform. The primary feature is expected to determine things like the splash screen and other characteristics that give Eclipse its identity. Eclipse allows only one primary feature. In this way — by creating a set of plug-ins, packaging them into a feature, and making this feature the primary feature — Eclipse can be re-branded and used to create an entirely new and different product. As downloaded from Eclipse.org, the default primary feature is eclipse.org.platform.


Next steps

This introduction to plug-ins necessarily covers very little of what can be done with a plug-in. The best resource for learning more about plug-ins is the Plug-in Developer's Guide available from the help menu in Eclipse. The documentation includes a programming guide, a reference to the Eclipse API and the plug-in extension points, a guide to the programming examples available from Eclipse.org, and a list of frequently asked questions. Another excellent resource is the source code for Eclipse itself. Depending on your interests, you may wish to find examples of how different workbench features such as views and editors are extended, or how the SWT (the Eclipse graphics API) is used. In addition, the Resources below can help you learn more.

Resources

Learn

Get products and technologies

  • Download IBM product evaluation versions, and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
  • Innovate your next open source development project with IBM trial software, available for download or on DVD.

Discuss

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
  • Participate in developerWorks blogs and get involved in the developerWorks community.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology
ArticleID=10734
ArticleTitle=Developing Eclipse plug-ins
publish-date=12012002