Eclipse Platform
Update Packaging Conventions

Revision Date: 01/27/2003 9:00AM - Version: 2.0.19

Change History:

Table of Contents

Introduction
       Changes from 1.0
       Concepts
       Framework
Packaging Conventions
       Feature Archive
       Plug-In Archive
       Packaging NL
           Translated Feature Information
           Translated Plug-In Information
       Packaging Target-Specific Support
       Packaging Attribution Information
       Packaging Non-Plug-In Files
       Custom Install Handling
       Security Considerations
Update Server
       Site Map
       Default Site Layout
       Controlling Access
Eclipse Install
       Default Install Layout
       "Unmanaged" Plug-Ins
       Using Native Platform Installers

Introduction

This document outlines the support for managing the delivery of function within the Eclipse platform. Also refer to the " Eclipse.org Update Manager Agreement " for additional legal information governing the use of the Eclipse update manager function.

Changes from R1.0

This section describes the major design changes from the R1.0 Installation and Update support and supplies rationale for each design change.

Concepts

Plug-in
Eclipse developers build plug-ins. Plug-ins are the base units of execution recognized by the Eclipse runtime environment. In general, plug-ins are not exposed to users that select function during installation or update. The reason is that plug-in boundaries are established by developers for development reasons (like function reuse) and present the wrong level of granularity in terms of what the user sees as the unit of function.

While plug-ins are being developed (ie. are frequently being changed), their internal file structure will reflect what is convenient to the developer. This will generally depend on the particular development tool being used. Typically, however, the developer will likely setup the plug-in to execute from a directory tree containing exposed .class files, rather than executing from a .jar (requires an extra step to create the .jar and we all know developers hate extra steps). Also, at this stage the developer does not pay particular attention to plug-in versioning information, because the plug-in is continually changing.

However, when the plug-in is ready to be packaged, it needs to be converted to a form suitable for packaging and installation. Typically it means creation of the runtime .jar(s) and removing any development-time files (source, exposed .class files, etc). It also means updating the plugin.xml manifest with the formal plug-in version and reflecting the version in the plug-in directory name (see "Concurrent Plug-In Version Support" for details).

Plug-in Fragment
Plug-in Fragments (or simply Fragments) allow independent packaging of certain aspects of the base plug-in. This includes (but may not be limited to) translated resources for the plug-in, OS-specific or windowing-system-specific code. At runtime, fragments are logically merged into the base plug-in. From a packaging point of view, the install and update support does not really differentiate between plug-ins and their related fragments.

Feature
A feature is an installation packaging mechanism used to define a group of versioned plug-ins and/or plug-in fragments plus non-plug-in files that is used to deliver some user function. A feature can also include other features. Features are exposed to users as part of the packaging and installation process, because they represent a unit of function selection. Features also represent a unit of installation. Features carry a version identifier.

Features are packaged as a feature archive, referencing the required plug-ins, plug-in fragments and optional non-plug-in files. The feature archives are placed on an update server for download and installation by the Eclipse update manager, or they can be used as the input into a formal packaging process using one of the "traditional" installer technologies. The format of the feature archive is described later.

Framework

The 2.0 installation and update support is provided as a framework that allows custom implementations to be supplied for its key elements. In particular, the following can be supplied: Eclipse provides default implementations of feature and site. These are described in the rest of this document.
 
Note: The reminder of this document describes the default concrete implementation of the framework delivered with Eclipse. It specifies the structure of the default feature implementation, as well as the default site implementation, plus the corresponding xml files (feature.xml and site.xml). Providers of alternate concrete implementations can extend  parts or all of the default Eclipse implementation. This includes providing a mechanism for dynamic computation of the site map (site.xml)

Packaging Conventions

Default feature packages consist of several related files:

Feature Archive

The feature packaging information is placed into a separate Java .jar. Standard Java jar facilities are used for constructing feature archives. Feature archives reference separately packaged plug-in archives (see next section) and non-plug-in files.

Features are identified using a structured identifier based on the provider internet domain name. For example, organization eclipse.org may produce feature org.eclipse.javatooling. The character set used for feature identifiers is as specified for plug-in identifiers (see reference information describing the plug-in manifest).

The recommended convention for naming the feature archives is
<id>_<version>.jar

Where <id> is the feature identifier and <version> is the full version identifier contained in the respective feature.xml. Note that this is a recommended convention that minimizes chance of collisions, but is not required by the Eclipse architecture. For example, the following are valid feature archive names

org.eclipse.javatooling_1.0.3.jar
org.eclipse.pde_2.0.jar
my_feature.jar

Internally, each feature archive is packaged relative to its feature directory (but not including the directory path element). The archive has the following structure

feature.xml
feature<_locale>.properties (see "Translated Feature Information")
other feature files and subdirectories (TBD)
META-INF/
    Java jar manifest and security files

The feature install.xml format is defined by the following dtd:

<?xml encoding="ISO-8859-1"?>

<!ELEMENT feature (install-handler?, description?, copyright?, license?, url?, includes*, requires?, plugin*, data*)>
<!ATTLIST feature
    id            CDATA #REQUIRED
    version       CDATA #REQUIRED
    label         CDATA #IMPLIED
    provider-name CDATA #IMPLIED
    image         CDATA #IMPLIED
    os            CDATA #IMPLIED
    arch          CDATA #IMPLIED
    ws            CDATA #IMPLIED
    nl            CDATA #IMPLIED
    colocation-affinity
                  CDATA #IMPLIED
    primary       (true | false) "false"
    application   CDATA #IMPLIED
        plugin        CDATA #IMPLIED
>

<!ELEMENT install-handler EMPTY>
<!ATTLIST install-handler
    library       CDATA #IMPLIED
    handler       CDATA #IMPLIED
>

<!ELEMENT description (#PCDATA)>
<!ATTLIST description
    url           CDATA #IMPLIED
>

<!ELEMENT copyright (#PCDATA)>
<!ATTLIST copyright
    url           CDATA #IMPLIED
>

<!ELEMENT license (#PCDATA)>
<!ATTLIST license
    url           CDATA #IMPLIED
>

<!ELEMENT url (update?, discovery*)>

<!ELEMENT update EMPTY>
<!ATTLIST update
    url           CDATA #REQUIRED
    label         CDATA #IMPLIED
>

<!ELEMENT discovery EMPTY>
<!ATTLIST discovery
    url           CDATA #REQUIRED
    label         CDATA #IMPLIED
    type          (update|web) "update"
>

<!ELEMENT includes EMPTY>
<!ATTLIST includes
    id                CDATA #REQUIRED
    version           CDATA #REQUIRED 
    name              CDATA #IMPLIED
    optional          (true | false) "false" 
    match             (perfect | equivalent | compatible | greaterOrEqual) "compatible"      
    search-location   ( root | self | both) "root"
>

<!ELEMENT requires (import+)>

<!ELEMENT import EMPTY>
<!ATTLIST import
    plugin        CDATA #IMPLIED
    feature       CDATA #IMPLIED
    version       CDATA #IMPLIED
    id-match      (perfect | prefix) "perfect"

    match         (perfect | equivalent | compatible | greaterOrEqual) "compatible" 
    patch         (true | false) "false" 
>

<!ELEMENT plugin EMPTY>
<!ATTLIST plugin
    id            CDATA #REQUIRED
    version       CDATA #REQUIRED
    fragment      (true | false) "false"
    os            CDATA #IMPLIED
    arch          CDATA #IMPLIED
    ws            CDATA #IMPLIED
    nl            CDATA #IMPLIED
    download-size CDATA #IMPLIED
    install-size  CDATA #IMPLIED
>

<!ELEMENT data EMPTY>
<!ATTLIST data
    id            CDATA #REQUIRED
    os            CDATA #IMPLIED
    arch          CDATA #IMPLIED
    ws            CDATA #IMPLIED
    nl            CDATA #IMPLIED
    download-size CDATA #IMPLIED
    install-size  CDATA #IMPLIED
>

The element and attribute definitions are as follows:

When interacting with the update site, the feature implementation maps the <plugin> and <data> elements into path identifiers used by the site to determine the actual files to download and install. The default feature implementation supplied by Eclipse constructs the path identifiers as follows: Note, that in general the feature.xml  manifest documents should specify UTF-8 encoding. For example

<?xml version="1.0" encoding="UTF-8"?>

Translatable text contained in the feature.xml can be separated into feature<_locale>.properties files using Java property bundle conventions. Note that the translated strings are used at installation time (ie. do not employ the plug-in fragment runtime mechanism).

Plug-In Archive

Plug-ins and plug-in fragments are individually packaged as separate Java .jars. Standard Java jar facilities are used for constructing plug-in archives. There is no distinction made between a plug-in archive containing a plug-in and one containing a plug-in fragment.

The recommended convention for naming the plug-in archives is
<id>_<version>.jar

Where <id> is the plug-in or fragment identifier and <version> is the full version identifier contained in the respective plugin.xml or fragment.xml. Note that this is a recommended convention that minimizes chance of collisions, but is not required by the Eclipse architecture. For example, the following are valid plug-in archive names

org.eclipse.platform_1.0.3.jar
org.eclipse.ui.nl_2.0.jar
my_plugin.jar

Internally, each plug-in archive packages all the relevant plug-in or fragment files relative to its plug-in or fragment directory (but not including the directory path element). The archive has the following structure

plugin.xml *OR* fragment.xml
other plug-in or feature files and subdirectories
META-INF/
    Java jar manifest and security files

Packaging NL

In Eclipse, translated plug-in information is packaged either together with the base plug-in, or as a plug-in fragment. At runtime, Eclipse locates the translations for the required locale. The use of fragments allows translations to be added to the runtime without the need to repackage the base plug-ins.

This mechanism cannot be used for translating the actual packaging information that is part of the installation xml files. Consequently the standard Java translation conventions are used for the packaging information, and all necessary translations must be available at the time the feature is packaged.

Translated Feature Information

Note: This section describes the conventions used for translating the information contained within the feature manifest. It allows for the update client to select the correctly localized strings from the update server. This section specifically does not describe localization of individual plug-ins.

Several of the attributes within the feature manifest are strings intended for display through user interfaces. To facilitate translation, these attribute values use the convention defined for translatable attributes of plugin.xml. Strings beginning with % up to the first space are treated as resource identifier keys (without the %) and looked up in a properties file. For example

label="%cfg Tool Feature for Linux"

results in a resource lookup in the correct property file with key "cfg". If no property files are supplied, or the key is not found the default string value (following the %key) is used.

The property files are named as feature_<locale>.properties using the Java resource bundle naming conventions. Within the feature archive .jar they are placed in the same directory as their corresponding feature.xml file.

Implementation Note: When accessing the resource bundles the Eclipse installation and update code should create a class loader for accessing the translated string. This way, the standard locale lookup algorithm implemented by Java is automatically used.

ResourceBundle b;
ClassLoader l;
l = new URLClassLoader(new URL[] {<targetDirectoryURL>}, null);
b = ResourceBundle.getBundle("feature",Locale.getDefault(),l);

The resulting resource bundle can be used in IPluginDescriptor.getResourceString(String,ResourceBundle) to actually return the correct translated string for the manifest attribute.

Translated Plug-In Information

No change from 1.0. Translated plug-in information should be packaged as plug-in fragments.

Packaging Target-Specific Support

No change from 1.0. Target-specific plug-in support (os, ws) should be packaged as plug-in fragments.

Packaging Attribution Information

This topic is covered in separate documents available on the eclipse.org development resources page of the Update component.

Packaging Non-Plug-In Files

Arbitrary non-plug-in files can be included as part of the feature definition using the <data> elements. Non-plug-in files typically also requires specification of a custom install handler. In general, the Eclipse support only downloads the referenced non-plug-in files and calls the custom install handler to perform any actual installation steps.

Eclipse does not specify the format of the non-plug-in files.

Custom Install Handling

Custom install handlers are written as a Java class and are packaged as part of the feature archive . The installer must implement the IInstallHandler interface (in most cases will extend the BaseInstallHandler abstract helper class which implements IInstallHandler). When required, the install handler is dynamically loaded by the installation and update code, and is called at specific points during its processing. The install handler code has visibility to classes from the installation and update support plug-in, and its prerequisite plug-ins.

Implementation Note: the detailed list of visible prerequisite plug-ins is still evolving. It is expected to include org.eclipse.core.boot and org.eclipse.core.runtime in all cases, plus org.eclipse.ui and org.eclipse.swt when running with full workbench (ie. not "headless mode"). Also, it would be useful to always expose org.eclipse.core.ant so that build scripts can be used as part of the install handler implementation.

The IInstallHandler interface supports the following methods [Implementation Note: the detailed definition of the IInstallHandler interface is still evolving. The description below is not an API specification (simply a functional description)]:

Note, that as a general practice, install handlers should be provided in their own jars (even though they could be just exposed in the feature archive jar). The jar should be signed, and sealed.

Security Considerations

The general approach is to use base Java jar signing for the feature and plug-in archive .jars.

Features are verified as follows:

In general, when processing signed jars, the user will be prompted for each unrecognized certificate. The response choices will include aborting the installation (originator is not trusted), continuing the installation (originator is trusted for this installation).

Update Server

The default Eclipse update server is any URL-accessible server. The default implementation assumes a fixed-layout server. The content of the server (in terms of available features and plug-ins) is described in a site map file, site.xml. This file can be manually maintained, or can be dynamically computed by the server.

Site Map

The update server URL can be specified as a full URL to the site map file, or a URL of a directory path containing the site map file (similar to index.html processing). The site map site.xml format is defined by the following dtd:

<?xml encoding="ISO-8859-1"?>

<!ELEMENT site (description?, feature*, archive*, category-def*)>
<!ATTLIST site
    type          CDATA #IMPLIED
    url           CDATA #IMPLIED
>

<!ELEMENT description (#PCDATA)>
<!ATTLIST description
    url           CDATA #IMPLIED
>

<!ELEMENT feature (category*)>
<!ATTLIST feature
    type          CDATA #IMPLIED
    id            CDATA #IMPLIED
    version       CDATA #IMPLIED
    url           CDATA #REQUIRED
    label         CDATA #IMPLIED
    os            CDATA #IMPLIED
    arch          CDATA #IMPLIED
    ws            CDATA #IMPLIED
    nl            CDATA #IMPLIED
    patch         (true | false) "false"
>

<!ELEMENT archive EMPTY>
<!ATTLIST archive
    path          CDATA #REQUIRED
    url           CDATA #REQUIRED
>

<!ELEMENT category EMPTY>
<!ATTLIST category
    name          CDATA #REQUIRED
>

<!ELEMENT category-def (description?)>
<!ATTLIST category-def
    name          CDATA #REQUIRED
    label         CDATA #REQUIRED
>

The element and attribute definitions are as follows:

Note, that in general the feature.xml  manifest documents should specify UTF-8 encoding. For example

<?xml version="1.0" encoding="UTF-8"?>

Translatable text contained in the site.xml can be separated into site<_locale>.properties files using Java property bundle conventions. Note that the translated strings are used at installation time (ie. do not employ the plug-in fragment runtime mechanism). The property bundles are located relative to the site.xml location.

Default Site Layout

<site root>/
    site.xml
    features/
        feature archives   (eg. org.eclipse.javatools_1.0.1.jar)
        <featureId>_<featureVersion>/    (optional)
            non-plug-in files for feature
    plugins/
        plug-in argives    (eg. org.eclipse.ui_1.0.3.jar)

Controlling Access

The default Eclipse site implementation provides support for http access with basic user authentication (userid and password).

Custom access control mechanisms can be added to base Eclipse in one of 2 ways:

Eclipse provides an example demonstrating an implementation of an access mechanism based on feature key files.

Eclipse Install

Default Install Layout

<install root>/
    install/
        features/
            <featureId>_<version>/
                feature.xml
                other feature files
                META-INF/
                META-INF-ECLIPSE/

    plugins/
        <pluginORfragmentId>_<version>/
            plugin.xml or fragment.xml
            other plugin or fragment files
            META_INF/

Implementation Note: we will go back to the original design of not splitting out fragments (ie. plugin and fragments go into the same install location)

"Unmanaged" Plug-Ins

Eclipse supports a concept of "unmanaged" plug-ins. These are plug-ins that were directly installed into the Eclipse file tree without being part of a feature (eg. developer unzipping plug-in archive directly into the Eclipse file tree).

Eclipse runtime recognizes these plugins during startup and loads the plug-in information into the runtime registry following the standard plug-in binding rules. The update support also recognizes the presence of this new plug-in, but since this plug-in is not part of any feature it cannot be updated using the update support (hence "unmanaged"). Unmanaged plug-in that become referenced by a feature as a result of some future installation or update action become "managed" (can be updated as part of the feature).

Unmanaged plug-ins are not displayed as part of the installation and update UI.

Using Native Platform Installers

The Eclipse installation contains plugins that can be shared across multiple features. When installing and uninstalling features using the Eclipse installation and update support, these relationship are correctly maintained. Only one copy of any version of a plug-in is used.

However, when using native platform installers, performing native uninstall creates problems because plug-ins would be removed without regard to any sharing relationships. As a result, Eclipse does not allow plug-ins to be installed using native installers into the shared installation tree. Instead, native installers must establish their own installation root directory. The subdirectory structure is the same as defined for base Eclipse. The private root directory is logically linked into the shared Eclipse installation via a link file installed by the native installer. The file path for the link file is <configRoot>/links/. The <configRoot> location is computed by Eclipse relative to the launch configuration file . By default, this is the install/ directory in the shared Eclipse installation tree.

The name of the link file is not specified by Eclipse. The name is determined by the native installer. To minimize the potential for naming collisions, it is recommended that the file name contain the identifier and version of the feature being installed by the native installer. For example, <featureId>_<featureVersion>.properties . The file content is in the form of a Java properties file, with the following properties defined:

path=[r|rw] install-path[,[r|rw] install-path]*

The property path is a comma-separated list of optionally annotated install paths. The property value install-path is a full file path to the installation directory root, specified in local OS format. The optional annotation r or rw indicates whether Eclipse update support should allow the specified location to be used for updates. Default is to allow updates  (w).

Eclipse does not manage the linked directories in any way. It simply detects their existence by the presence of the link files, and includes the linked plug-ins during the platform startup. The native installer is responsible for uninstalling the link when the corresponding directory is removed. Eclipse runtime ignores any links that cannot be resolved.