Support free tutorials

vogella training Training Books

Eclipse p2 updates for RCP applications - Tutorial

Lars Vogel

Version 2.5


Eclipse p2 - Updates

This tutorial describes how to integrate update functionality into Eclipse RCP applications using Eclipse p2.

This tutorial is based on Eclipse 4.2

Table of Contents

1. Prerequisites
2. Eclipse application updates with p2
2.1. Eclipse application updates
2.2. Creating p2 update sites
3. Required plug-ins for updates
4. Updating Eclipse RCP applications
5. Exercise preparation: Create a update enabled RCP application
6. Exercises: Application update
6.1. Select update location
6.2. Add dependencies
6.3. Add feature to product
6.4. Create user interface
6.5. Enter version in your product configuration file
6.6. Create initial product export
6.7. Start export application and check for updates
6.8. Make change and export product again
6.9. Update application
7. p2 composite repositories
8. Learn more about Eclipse 4 RCP development
9. About this website
9.1. Donate to support free tutorials
9.2. Questions and discussion
9.3. License for this tutorial and its code
10. Links and Literature
10.1. Eclipse p2 updater resources
10.2. vogella Resources

1. Prerequisites

This tutorial assumes that you have a basic understanding of development for the Eclipse platform. Please see Eclipse RCP Tutorial or Eclipse Plug-in Tutorial. It also assumes that you know how to create Eclipse feature projects. Please see Eclipse Feature and Fragment Tutorial for an introduction.

You should also know how to manually export products based on product configuration files, please see Eclipse product and deployment.

2. Eclipse application updates with p2

2.1. Eclipse application updates

The Eclipse platform provides an installation and update mechanism called Eclipse p2 (short: p2). This update mechanism allows you to update Eclipse applications and to install new functionalities.

The update and installation of functionalities with p2 is based on feature projects (short: features) projects. It is possible to update complete products or individual features. In the terminology of p2 these features are installable units.

2.2. Creating p2 update sites

Installable units can be grouped into a p2 repository. A repository is defined via its URI and can point to a local file system or to a web server. A p2 repository is also frequently called update site.

During the export of an Eclipse application you can select the Generate p2 repository option in the Eclipse product export dialog. This option is highlighted in the following screenshot.

Selection in the export wizard for the metadata repository creation

If you select this option, an update site is created in a sub-folder called repository of the export directory.

Typically this directory is copied to a web server so users can install new functionality or upgrades using the p2 mechanism. The Eclipse update mechanism also supports file based update sites. File based update sites are useful for testing the update functionality.

An update site contains an artifact and a metadata repository.

3. Required plug-ins for updates

The following table lists the core plug-ins and the feature which provide the non-user interface functionality of p2.

Table 1. Eclipse p2 plug-ins and features

Plug-in Description
org.eclipse.equinox.p2.core Core p2 functionality
org.eclipse.equinox.p2.engine The engine carries out the provisioning operation.
org.eclipse.equinox.p2.operations Layer over the core and engine API to describe updates as an atomic install.
org.eclipse.equinox.p2.metadata.repository Contains the definition of p2 repositories.
org.eclipse.equinox.p2.core.feature Feature containing the p2 bundles.

To use the Eclipse update API you need to include these plug-ins as dependencies to your MANIFEST.MF file and you must add the feature to your product configuration file.

4. Updating Eclipse RCP applications

To update your Eclipse 4 application you use the p2 API. The following code shows an example handler which performs an update of a complete Eclipse RCP application. The method annotated with @Execute initializes the p2 update engine and configures the location for the artifact and metadata repository. Afterwards these repositories are checked for changes. If updates are found, these updates are installed into the application. The last step is to run the update.

package com.example.e4.rcp.todo.handlers;


import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.operations.ProvisioningJob;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.UpdateOperation;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;

// Require-Bundle: org.eclipse.equinox.p2.core|engine|operation|metadata.repository
// Feature: org.eclipse.equinox.p2.core.feature
// !!! Do not run from within IDE. Update only works in an exported product !!!
public class UpdateHandler {
  private static final String REPOSITORY_LOC = System.getProperty("UpdateHandler.Repo", "http://localhost/repository");

  public void execute(final IProvisioningAgent agent, final Shell shell,
      final UISynchronize sync, final IWorkbench workbench,
      final Logger logger) {
    Job j = new Job("Update Job") {
      protected IStatus run(final IProgressMonitor monitor) {
        return checkForUpdates(agent, shell, sync, workbench, monitor,

  private IStatus checkForUpdates(final IProvisioningAgent agent,
      final Shell shell, final UISynchronize sync,
      final IWorkbench workbench, IProgressMonitor monitor, Logger logger) {

    /* 1. configure update operation */
    final ProvisioningSession session = new ProvisioningSession(agent);
    final UpdateOperation operation = new UpdateOperation(session);
    configureUpdate(operation, logger);

    /* 2. Check for updates */

    // run check if updates are available (causing I/O)
    final IStatus status = operation.resolveModal(monitor);

    // Failed to find updates (inform user and exit)
    if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
      showMessage(shell, sync);
      return Status.CANCEL_STATUS;

    /* 3. run installation */
    final ProvisioningJob provisioningJob = operation

    // updates cannot run from within Eclipse IDE!!!
    if (provisioningJob == null) {
      logger.error("Maybe you are trying to update from the Eclipse IDE? This won't work!!!");
      return Status.CANCEL_STATUS;
    configureProvisioningJob(provisioningJob, shell, sync, workbench);

    return Status.OK_STATUS;


  private void configureProvisioningJob(ProvisioningJob provisioningJob,
      final Shell shell, final UISynchronize sync,
      final IWorkbench workbench) {

    // Register a job change listener to track
    // installation progress and notify user upon success
    provisioningJob.addJobChangeListener(new JobChangeAdapter() {
      public void done(IJobChangeEvent event) {
        if (event.getResult().isOK()) {
          sync.syncExec(new Runnable() {

            public void run() {
              boolean restart = MessageDialog
                      "Updates installed, restart?",
                      "Updates have been installed successfully, do you want to restart?");
              if (restart) {



  private void showMessage(final Shell parent, final UISynchronize sync) {
    sync.syncExec(new Runnable() {

      public void run() {
            .openWarning(parent, "No update",
                "No updates for the current installation have been found");

  private UpdateOperation configureUpdate(final UpdateOperation operation,
      Logger logger) {
    // create uri and check for validity
    URI uri = null;
    try {
      uri = new URI(REPOSITORY_LOC);
    } catch (final URISyntaxException e) {
      return null;

    // set location of artifact and metadata repo
    operation.getProvisioningContext().setArtifactRepositories(new URI[] { uri });
    operation.getProvisioningContext().setMetadataRepositories(new URI[] { uri });
    return operation;

5. Exercise preparation: Create a update enabled RCP application

Create an Eclipse 4 RCP project called com.example.e4.rcp.todo based on the Eclipse 4 wizard.

6. Exercises: Application update

6.1. Select update location

Choose a local file system path as the location for the update site. This path will be referred to as REPOSITORY_LOC.

6.2. Add dependencies

Add the plug-in dependencies from Section 3, “Required plug-ins for updates” to your application plug-in.

6.3. Add feature to product

Add the org.eclipse.equinox.p2.core.feature feature to your product configuration file. Use the Dependencies tab for that.

6.4. Create user interface

Create a new menu entry in your application menu with the Update label. Implement a new handler for this menu entry.

See Section 4, “Updating Eclipse RCP applications” for an example implementation. Ensure to adjust the REPOSITORY_LOC constant in this code. It should point to your file location from Section 6.1, “Select update location”.

6.5. Enter version in your product configuration file

Ensure that you have entered a version number for the product and to append the ".qualifier" suffix to the product version.

Enter version in the product configuration files

6.6. Create initial product export

Export your product via the Eclipse Product export wizard on the Overview tab of the product file.


Do not choose the REPOSITORY_LOC path as destination.

This application will be updated later.

6.7. Start export application and check for updates

Start your exported application from the export directory. Check for updates by invoking your update handler. Your handler reports that updates cannot be found.

6.8. Make change and export product again

Change a (visible) label in your application and increment the product version on the overview page of the product editor to indicate a functional change.

Export your product again. Use a different folder than the first time. You don't want to override the existing exported application. Make sure to select the Generate p2 repository option on the export dialog.


Again, do not export to the REPOSITORY_LOC path.

In the new export folder you find a sub-folder called repository. Copy this sub-folder to the REPOSITORY_LOC path.

6.9. Update application

Start your exported application from Section 6.6, “Create initial product export” and check again for updates via your menu entry. If everything was implemented correctly, your handler should report that updates are available. Install these updates and restart the application.


In case your handler does not find the update, restart your application to clear caches.

Verify that all updates have been applied.

7. p2 composite repositories

It is possible to create p2 composite repositories. Such a repository wraps the information about other repositories. If a client connects to such an update site, the other update sites are contacted and the user can install features from the other update site.

To build such a composite repository you have to create two files, one called compositeContent.xml and another called compositeArtifacts.xml. The following example demonstrates the content of these files.

The following listing is an example for an compositeContent.xml file.

<?xml version='1.0' encoding='UTF-8'?>
<?compositeMetadataRepository version='1.0.0'?>
<repository name='&quot;oclipse development environment&quot;'
  <properties size='1'>
    <property name='p2.timestamp' value='1243822502499' />
  <children size='2'>
      <child location=''/>
      <child location=''/>

The following listing is an example for a fitting compositeArtifacts.xml file.

<?xml version='1.0' encoding='UTF-8'?>
<?compositeArtifactRepository version='1.0.0'?>
<repository name='&quot;voclipse development environment&quot;'
  <properties size='1'>
    <property name='p2.timestamp' value='1243822502440' />
  <children size='2'>
    <child location='' />
    <child location='' />

8. Learn more about Eclipse 4 RCP development

I hope you enjoyed this tutorial. You find this tutorial and much more information also in the Eclipse 4 RCP book from this author.

9. About this website

9.1. Donate to support free tutorials

Please consider a contribution Support free tutorials if this article helped you. It will help to maintain our content and our Open Source activities.

9.2. Questions and discussion

Writing and updating these tutorials is a lot of work. If this free community service was helpful, you can support the cause by giving a tip as well as reporting typos and factual errors.

If you find errors in this tutorial, please notify me (see the top of the page). Please note that due to the high volume of feedback I receive, I cannot answer questions to your implementation. Ensure you have read the vogella FAQ as I don't respond to questions already answered there.

9.3. License for this tutorial and its code

This tutorial is Open Content under the CC BY-NC-SA 3.0 DE license. Source code in this tutorial is distributed under the Eclipse Public License. See the vogella License page for details on the terms of reuse.

10. Links and Literature

10.2. vogella Resources

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”. The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.