Eclipse 3.0 Porting Guide

Draft for 3.0 M8
Last revised February 26, 2004

Note: This is a work in progress. An up-to-date draft of the Eclipse 3.0 Porting Guide is being included with each milestone build to facilitate climbing aboard the 3.0 release wagon at an early stage, or to estimate the amount of effort that will be involved in eventually porting existing plug-ins to 3.0. While we will continue to improve and refine this porting guide and to document any further areas requiring attention, the significant breaking changes to the Eclipse APIs are now behind us.

This porting guide describes how to port existing 2.1 plug-ins to 3.0. It is organized as follows:

Required Changes for 3.0

This section describes changes that impact existing plug-ins. If your plug-in is affected, you will have to change your plug-in in order to get it to work properly with Eclipse 3.0.

Plug-in manifest version

The header of the manifest files for plug-ins (and plug-in fragments) has changed to include a new line which identifies the appropriate plug-in manifest version. Prior to 3.0, plug-ins did not carry one of these <?eclipse ...?> lines; after 3.0, they must always have one. This change is to allow the Eclipse runtime to reliably recognize pre-3.0 plug-ins that have not been ported to 3.0, so that it can automatically provide greater binary compatibility for such plug-ins. This is the general form of the plugin.xml file (fragment.xml is similar):

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin ...>
    ...
</plugin>

When porting to 3.0, add the indicated line to the manifest of existing plug-ins and plug-in fragments. (The PDE plug-in migration tool adds this line.)

If you do add this directive to a plugin.xml (manually or using PDE), the file must also be updated to explicitly list the plug-ins on which it depends. For example, prior to Eclipse 3.0 dependencies on org.eclipse.core.runtime and org.eclipse.core.boot were implicit. With 3.0, org.eclipse.core.boot is no longer needed and developers must choose org.eclipse.core.runtime or org.eclipse.core.runtime.compatibility (or neither) as appropriate.

Restructuring of org.eclipse.ui plug-in

The org.eclipse.ui plug-in, which used to be the main Platform UI plug-in, now provides just the API and extension points for the generic (i.e., non-IDE-specific) workbench. Optional and IDE-specific API and extension points have moved to other plug-ins.

The impact of this change is two-fold: (1) the moved org.eclipse.ui extension points have new extension point ids; and (2) the list of required plug-ins has changed.

N.B. The Eclipse 3.0 runtime automatically detects pre-3.0 plug-ins (by the absence of the aforementioned <?eclipse...?> line in the plug-in manifest) and automatically compensates for these extension point and plug-in dependency changes. This should be viewed as a stopgap measure that increases the likelihood that an existing plug-in that depends on org.eclipse.ui will work in 3.0. However, when porting the existing plug-in to 3.0, the plug-in's manifest needs to be updated to reflect the new structure of the Eclipse UI plug-ins.

The org.eclipse.ui extension points in the following table have moved to different plug-ins, causing their extension point ids to change. If an existing plug-in contributes an extension to the moved extension points, then the reference in the "point" attribute of the <extension> element in the plug-in manifest file must be changed to refer to the corresponding new ones extension point id. (The PDE plug-in migration tool makes these fix-ups.)

Old extension point id

New extension point id

org.eclipse.ui.markerHelp org.eclipse.ui.ide.markerHelp
org.eclipse.ui.markerImageProviders org.eclipse.ui.ide.markerImageProviders
org.eclipse.ui.markerResolution org.eclipse.ui.ide.markerResolution
org.eclipse.ui.projectNatureImages org.eclipse.ui.ide.projectNatureImages
org.eclipse.ui.resourceFilters org.eclipse.ui.ide.resourceFilters
org.eclipse.ui.markerUpdaters org.eclipse.ui.editors.markerUpdaters
org.eclipse.ui.documentProviders org.eclipse.ui.editors.documentProviders
org.eclipse.ui.workbench.texteditor.
markerAnnotationSpecification
org.eclipse.ui.editors.markerAnnotationSpecification

The following table lists the API packages formerly provided by the org.eclipse.ui plug-in that have been moved to different plug-ins. (The names of the API packages, classes, fields, and methods did not change.) In some cases, the API packages are now split across more than one plug-in. Since the API classes visible to any given plug-in are determined by that plug-in's list of required plug-ins, these changes may require adjusting "<requires>" elements in an existing plug-in's manifest to regain access to API class.

This change only affects plug-ins that depend on the org.eclipse.ui plug-in (that is, includes <import plugin="org.eclipse.ui"/> in the <requires> section of the plug-in manifest); all other plug-ins are unaffected. If it is affected, you may need to change the <import> element, or add additional <import> elements, so that all the API classes your plug-in needs are in scope. We strongly recommend that plug-ins only state dependencies on the plug-ins that they actually use. Including unnecessary dependencies reduces runtime performance because the Java class loader must search for classes in all dependents. (The PDE plug-in migration tool will fix up the dependencies, and help to determine a minimal set.)

API package

2.1 plug-in

Corresponding 3.0 plug-in(s)

org.eclipse.jface.text.* org.eclipse.ui org.eclipse.jface.text
org.eclipse.text.* org.eclipse.ui org.eclipse.jface.text
org.eclipse.ui org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.actions org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.dialogs org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.editors.* org.eclipse.ui org.eclipse.ui.editor
org.eclipse.ui.model org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.part org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.texteditor org.eclipse.ui org.eclipse.ui.workbench.texteditor, org.eclipse.ui.editors
org.eclipse.ui.texteditor.* org.eclipse.ui org.eclipse.ui.workbench.texteditor
org.eclipse.ui.views.bookmarkexplorer org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.contentoutline org.eclipse.ui org.eclipse.ui.views
org.eclipse.ui.views.markers org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.navigator org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.properties org.eclipse.ui org.eclipse.ui.views
org.eclipse.ui.views.tasklist org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.wizards.datatransfer org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.wizards.newresource org.eclipse.ui org.eclipse.ui.ide

Changes to API classes and interfaces (by package)

IWorkbench (package org.eclipse.ui)

IWorkbenchPage (package org.eclipse.ui)

IEditorPart (package org.eclipse.ui)

EditorPart (package org.eclipse.ui.part)

MultiEditor (package org.eclipse.ui.part)

MultiPageEditor (package org.eclipse.ui.part)

MultiPageEditorPart (package org.eclipse.ui.part)

IEditorLauncher (package org.eclipse.ui)

IEditorRegistry (package org.eclipse.ui)

AbstractDocumentProvider (package org.eclipse.ui.texteditor)

AbstractTextEditor (package org.eclipse.ui.texteditor)

StatusTextEditor (package org.eclipse.ui.texteditor)

ExtendedTextEditor (package org.eclipse.ui.editors.text)

StorageDocumentProvider (package eclipse.ui.editors.text)

FileDocumentProvider (packge org.eclipse.ui.editors.text)

Generic Console

With the work for the generic console support, the view id for the console has changed from org.eclipse.debug.ui.ConsoleView. This results in problems at startup such as "Could not restore workbench layout" with details that "Could not create view: org.eclipse.debug.ui.ConsoleView" for the particular perspective that contained reference to the old view id. The equivalent view id is now: "org.eclipse.ui.console.ConsoleView".
The generic console is available via the Window>Show View>Basic>Console and is used by the Eclipse debug and Ant integration.

[JDT only] IJavaBreakpointListener (package org.eclipse.jdt.debug.core)

In 3.0, the return types for the methods IJavaBreakpointListener.breakpointHit(IJavaBreakpoint, IJavaThread) and installingBreakpoing(IJavaTarget, IJavaBreakpoint, IJavaType) changed from boolean to int to allow listeners to vote "don't care". In releases prior to 3.0, listeners could only vote "suspend" or "don't suspend" when a breakpoint was hit, and "install" or "don't install" when a breakpoint was about to be installed. In 3.0, listeners can also vote "don't care" for either of these notifications. This allows clients to only make a decisive vote in situations that they care about. For "breakpoint hit" notifications, the breakpoint will suspend if any listeners vote "suspend", or all listeners vote "don't care"; and it will not suspend if at least one listener votes "don't suspend" and no listeners vote "suspend". Similarly, for "breakpoint installing" notifications, the breakpoint will be installed if any listeners vote to install, or all listeners vote "don't care"; and it will not be installed if at least one listener votes "don't install" and no listeners vote "install". In general, implementors should return DONT_CARE unless they have a strong opinion one way or the other. It is important to keep in mind, for example, that voting "suspend" will override any other listener's vote of "don't suspend".

The IJavaBreakpointListener interface is implemented by clients that create or react to breakpoints in Java code. There are likely few clients beyond JDT itself, save the one that reported the problem (bug 37760) that this change remedies. This is a breaking change for existing code that implements the IJavaBreakpointListener interface. This code needs to be modified to return an appropriate int value before it will compile or run in 3.0.

Clipboard access in UI thread (package org.eclipse.swt.dnd)

Prior to 3.0, the methods on the SWT Clipboard class were tacitly permitted to run in threads other than the UI thread. This oversight resulted in failures on GTK where the operating system requires that clipboard interactions be performed in the UI thread. The oversight was not revealed earlier because many applications are single-threaded and receive most of their testing on Windows. In order for the Clipboard API to be sustainable and cross-platform, in 3.0 the specification and implementation of all Clipboard API methods have been changed to throw an SWT Exception (ERROR_THREAD_INVALID_ACCESS) if invoked from a non-UI thread. Clipboard services are commonly provided automatically by Eclipse components such as the text editor, which insulate many clients from this breaking change. Existing code that does make direct use of Clipboard should ensure that the API methods are called on the correct thread, using Display.asyncExec or syncExec as required to shift accesses into the UI thread.

SWT.KeyDown events

In 3.0 key down events are reported before the work is done in the OS. This is much earlier than it was prior to 3.0. This change was made to support key bindings in Eclipse which necessitates intercepting key events before any widget had a chance to process the character. Consequences of this change are visible to code that handles low-level SWT.KeyDown events directly. For example, it means that when a listener on a Text widget receives a key down event, the widget's content (getText()) will not yet include the key just typed (it would have prior to 3.0). The recommended way to get the full text from the widget including the current key is to handle the higher-level SWT.Modify or SWT.Verify events rather than the low-level SWT.KeyDown event; code that does it this way is unaffected by this change.

Tab traversal of SWT Canvas (package org.eclipse.swt.widgets)

Prior to 3.0, when the focus was in an SWT Canvas or one of its subclasses (including custom widgets), typing Ctrl+Tab, Shift+Tab, Ctrl+PgUp, or Ctrl+PgDn would automatically trigger traversal to the next/previous widget without reporting a key event. This behavior was unspecified, and runs counter to the rule that Canvases see every key typed in them. The proper way to handle traversal is by registering a traverse listener. In order to properly support Eclipse key bindings in 3.0, the default behavior was changed so that Canvas now sees Ctrl+Tab, Shift+Tab, Ctrl+PgUp, and Ctrl+PgDn key events instead of traversing. If you use a raw Canvas or define a subclass of Canvas, ensure that that you register a traverse listener.

Selection event order in Table and Tree widgets

Mouse selections of items in SWT Table and Tree widgets generate the event sequence MouseDown-Selection-MouseUp uniformly in all operating environments. Similarly, keyboard selections generate the event sequence KeyDown-Selection-KeyUp uniformly in all operating environments. Prior to 3.0, the event order was not uniform, with Motif and Photon at variance with the rest by always reporting the Selection event first; i.e., Selection-MouseDown-MouseUp or Selection-KeyDown-KeyUp. For 3.0, the event order on Motif and Photon has been changed to match the others. Existing code that was functioning correctly on {Windows, GTK} and on {Motif, Photon} is unlikely to be affected. But it is wise to check your code to ensure that it does not rely on an invalid event order.

IResourceChangeEvent (org.eclipse.core.resources)

In Eclipse 3.0, workspace auto-build now occurs in a background thread. This required an API contract change to IResourceChangeEvent. The contract of IResourceChangeEvent previously guaranteed the following ordering of events for all workspace changes:

  1. PRE_DELETE or PRE_CLOSE event notification if applicable
  2. Perform the operation
  3. PRE_AUTO_BUILD event notification
  4. If auto-build is on, perform incremental workspace build
  5. POST_AUTO_BUILD event notification
  6. POST_CHANGE event notification

With auto-build now running in the background, there is no longer any guarantee about the temporal relationship between the AUTO_BUILD events and the POST_CHANGE event. In Eclipse 3.0, steps 3-5 in the above structure are removed from the operation. The resulting picture looks like this:

  1. PRE_DELETE or PRE_CLOSE event notification if applicable
  2. Perform the operation
  3. POST_CHANGE event notification

Periodically, the platform will perform a background workspace build operation. Note that this happens regardless of the whether auto-build is on or off. The exact timing of when this build occurs will not be specified. The structure of the build operation will look like this:

  1. PRE_AUTO_BUILD event notification
  2. If auto-build is on, perform incremental workspace build
  3. POST_AUTO_BUILD event notification
  4. POST_CHANGE event notification
The reference point for the deltas received by auto-build listeners will be different from post-change listeners. Build listeners will receive notification of all changes since the end of the last build operation. Post-change listeners will receive a delta describing all changes since the last post-change notification. This new structure retains three characteristics of resource change listeners that have been true since Eclipse 1.0: However, there are some important differences with this approach. Prior to Eclipse 3.0, auto-build listeners were always called before POST_CHANGE listeners. For this reason, the delta received by auto-build listeners was always a subset of the delta received by the POST_CHANGE listeners. This relationship is now essentially reversed. Auto-build listeners will receive a delta that is a super-set of all deltas supplied to POST_CHANGE listeners since the end of the last background build. As before, auto-build listeners will be allowed to modify the workspace, and post-change listeners will not.

It will no longer be true that upon completion of a workspace changing operation, that AUTO_BUILD event listeners will have been notified. Client code that registers resource change listeners with IWorkspace.addResourceChangeListener(IResourceChangeListener) is  unlikely to be affected by this change because AUTO_BUILD events were never reported to these listeners. However, clients that use IWorkspace.addResourceChangeListener(IResourceChangeListener,int) and specify an event mask that includes AUTO_BUILD events are likely to be broken by this change if they make assumptions about when auto-build listeners run or what thread they run in. For example, if an auto-build listener is updating a domain model to reflect changes to the workspace, then this update might not have happened when the workspace changing operation returns. It is worth noting that only UI-level code can be affected in this way. Core-level code that is called via API may be called within the scope of an IWorkspaceRunnable, so it can never be sure about when resource change listeners will be called. The suggested fix for this breakage is to use POST_CHANGE instead of build listeners if it is necessary to have notification occur before the operation completes.

IWorkspaceRunnable and IWorkspace.run

It will no longer be guaranteed that all resource changes that occur during the dynamic scope of an IWorkspaceRunnable will be batched in a single notification. This mechanism can still be used for batching changes to avoid unnecessary builds and notifications, but the platform may now decide to perform notifications during the operation. This API contract change is not likely to be a breaking change for existing clients. It is equivalent to the platform deciding to call IWorkspace.checkpoint periodically during a long running operations. The reason for this change is that it is now possible for multiple threads to be modifying the workspace concurrently. When one thread finishes modifying the workspace, a notification is required to prevent responsiveness problems, even if the other operation has not yet completed. This change also allows users to begin working on a set of resources before the operation completes. For example, a user can now begin browsing files in a project that is still in the process of being checked out. The new method IWorkspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) has an optional flag, AVOID_UPDATE, that operations can use as a hint to the platform to specify whether periodic updates are desired.

Eclipse 3.0 is more concurrent

Prior to Eclipse 3.0, Eclipse operated mostly in a single thread. Most API methods and extension points operated either in the UI thread, or in a thread spawned from a progress dialog that blocked the UI thread. Most plug-in writers did not have to worry much about thread safety, apart from ensuring that all UI activity occurred in the UI thread. In Eclipse 3.0, there is generally much more concurrency. Many operations now occur in a background thread, where they may run concurrently with other threads, including the UI thread. All plug-ins whose code runs in a background thread must now be aware of the thread safety of their code.

In addition to plug-ins that are explicitly running operations in the background using the org.eclipse.core.runtime.jobs API, there are several platform API facilities and extension points that make use of background threads. Plug-ins that hook into these facilities need to ensure that their code is thread safe. The following table summarizes the API and extension points that run some or all of their code in a background thread in Eclipse 3.0:

 

Extension point or API class

Notes

org.eclipse.core.runtime.IRegistryChangeListener New in Eclipse 3.0, runs in background
org.eclipse.core.resources.IResourceChangeListener AUTO_BUILD events now in background
org.eclipse.core.resources.builders Autobuild now in background
org.eclipse.core.resources.ISaveParticipant SNAPSHOT now in background
org.eclipse.ui.workbench.texteditor.quickdiffReferenceProvider New in Eclipse 3.0, runs in background
org.eclipse.ui.decorators Already in background in Eclipse 2.1
org.eclipse.ui.startup Already in background in Eclipse 2.1
org.eclipse.team.core.org.eclipse.team.core.repository Many operations now in background
org.eclipse.team.ui.synchronizeParticipants New in Eclipse 3.0, runs in background
org.eclipse.debug.core.launchConfigurationTypes Now runs in background
org.eclipse.jdt.core.IElementChangedListener PRE_AUTO_BUILD now runs in background, POST_RECONCILE already ran in the background

There are various strategies available for making code thread safe. A naive solution is to ensure all work occurs in the UI thread, thus ensuring serialized execution. This is a common approach for UI plug-ins that are not doing CPU-intensive processing. When doing this, be aware of the deadlock risk inherent in Display.syncExec. Display.asyncExec is generally safer as it does not introduce deadlock risk, at the expense of losing precise control over when the code is executed.

Other techniques for making thread safe code included:

Restructuring of Platform Core Runtime

The Eclipse 3.0 Platform Runtime is based on OSGi, necessitating changes to the structure of the two Platform Runtime plug-ins, org.eclipse.core.runtime and org.eclipse.core.boot.

A new org.eclipse.core.runtime.compatibility plug-in provides an implementation bridge between the old and new APIs, and is the new home for some of the obsolete APIs formerly found in org.eclipse.core.runtime and org.eclipse.core.boot. Obsolete API will be deprecated in a future release in favor of the OSGi-based API, once these new APIs have stabilized and matured. The new OSGi-based Eclipse Runtime API is available in the org.eclipse.core.runtime plug-in for early adopters wishing to take advantage of its new capabilities. Platform Runtime extension points were not affected by the restructuring.

N.B. The Eclipse 3.0 runtime automatically detects pre-3.0 plug-ins (by the absence of the aforementioned <?eclipse...?> line in the plug-in manifest) and automatically compensates for these changes to the Platform Runtime. This should be viewed as a stopgap measure to allow existing plug-in that explicitly or implicitly depends on org.eclipse.core.runtime or org.eclipse.core.boot to work in 3.0. However, when porting the existing plug-in to 3.0, the plug-in's manifest needs to be updated to reflect the new structure of the Eclipse Platform Runtime plug-ins. The PDE plug-in manifest migration tool will add a dependency to org.eclipse.core.runtime.compatibility if required.

Note also that if you mark you plug-in as 3.0 (using <?eclipse...?>) and your plug-in defines a Plugin class, you must either explicitly <import plugin="org.eclipse.core.runtime.compatibility"/> in the plug-in manifest or ensure that the Plugin class defines the default constructor.

URL Stream Handler extensions

The contract for the org.eclipse.core.runtime.urlHandlers extension point was changed to use the URL Stream Handler service provided by OSGi. The OSGi support is superior to the one in Eclipse 2.1, and correctly handles dynamic handlers. Because of various design issues with the base Java URL handler mechanism, URLStreamHandlers registered with the OSGi handler service must implement org.osgi.service.url.URLStreamHandlerService.

The change affects plug-ins that contribute extensions to the org.eclipse.core.runtime.urlHandlers extension point. Formerly, the main class had to implement java.net.URLStreamHandler. It needs to be updated to implement org.osgi.service.url.URLStreamHandlerService interface. The OSGi framework provides an abstract base class (org.osgi.service.url.AbstractURLStreamHandlerService) that can be subclassed.

Classload order

Who is affected: Plug-ins which supply packages provided which are also supplied by other plug-ins. A very limited number of plug-ins are affected by this change and some of those affected will actually benefit (see below).

Description: In Eclipse 2.x, classloaders search for classes using the so-called PSP ordering. That is, a given classloader would first consult its parent classloader (in practice this is the Java boot classloader), then its own classpath contents (i.e., self) and finally all of its prerequisites in declared order. OSGi offers an optimization over this model, the so-called PP|S (read P, P or S) ordering. In this approach a classloader will consult its parent (again, effectively the Java boot classloader), then either a single prerequisite known to contribute classes in the package being queried then its own classpath entries for the desired class.

The classloader determines whether to consult self or its prerequisites based on its imported and required packages. This information is inferred from the plug-in content in the case of legacy plug-ins and directly specified in the case of new plug-ins. In either case, it is known a priori which classloaders will supply the classes for which packages. This offers performance improvements as well as a solution to the vexing problem of multiple prerequisites contributing the same classes.

Take for example the case of Xerces and Xalan. Both contain various classes from org.xml packages. Under the PSP model, the Xerces plug-in would see its copy of these classes while the Xalan plug-in would see their copy. Since these plug-ins need to communicate, ClassCastExceptions occur. Under the PP|S model, only one of the two plug-ins contributes the duplicate classes and both plug-ins see the same copies.

Action required: The action required depends on the particulars of the usecase. Affected developers need to review their classpath and resolve any conflicts which may be happening.

Class loader protection domain not set

Who is affected: Plug-ins which expect the protection domain of their class loader to be set at all times.

Description: In Eclipse 2.1 plug-in class loaders were SecureClassloaders. As such, they always had a protection domain set. In Eclipse 3.0 classloaders do not extend SecureClassloader and only set the protection domain if Java security is turned on (not the normal case).

Action required: The action required will depend on the scenario in which the plug-in is using the protection domain.

Default package content cannot be shared

Who is affected: Plug-ins which expect to use types or resources in the default package of another plug-in. The use of the default package is very rare. The only uses we have seen is where test suites use the default package and getResource() to access test data.

Description: The new Eclipse runtime allows plug-ins to contribute more classpath information. This information is used to optimize class loading such that searching arbitrarily long prerequisite chains is not required. The technique used for specifying this information does not allow for the sharing of the default package. As such, a plug-in's class loader is able to see the default package in its own classpath but not in that of its prerequisite plug-ins.

Action required: Plug-in developers should address this by moving such files to non-root directories on their classpath. Note that moving them to say icons/ in the jar does not particularly help because the package "icons" would typically be exported and would surely conflict with some other plug-in doing the same. Also note that Java package naming rules do not allow for package segments which contain whitespace. The best approach is to put the files in a real, unique, package (or remove such files from the classpath and access them via the new Bundle.getEntry() API).

PluginModel object casting

Who is affected: Plug-ins which cast objects of type IPlugin* to Plugin*Model. Even though the relationship between these interfaces and the model classes is not a specified part of the Eclipse 2.1 API we are explicitly calling out this change as we have found that PDE and a few others are currently take advantaging of the correlation in the 2.1 implementation.

Description: The Eclipse API provides a series of interfaces (e.g., IPluginDescriptor) and so-called "model" classes (e.g., PluginDescriptorModel) related to plug-ins and the plug-in registry. In the Eclipse 2.1 implementation it happens that the model classes implement the relevant interfaces. In the new runtime the plug-in registry has been significantly reworked to allow for a separation between the classloading and prerequisite aspects of plug-ins and the extension and extension-point aspects. As such the Eclipse 3.0 runtims is unable to maintain the implementation relationship present in 2.1.

Action required: Developers currently relying on this non-API relationship will need to rework their code according to their usecase. More information on this is given in the recommended changes section of this document.

ILibrary implementation incomplete

Who is affected: User of org.eclipse.core.runtime.ILibrary.

Description: The new runtime maintains the classpath entries in a different and incompatible form from Eclipse. As a result, the compatibility layer is unable to correctly model the underlying OSGi structures as ILibrary objects.

Action required: Users of ILibrary should consider accessing the desired header values (e.g., Bundle-Classpath) from the appropriate Bundle (see Bundle.getHeaders()) and using the ManifestElement helper class to interpret the entries.

Invalid assumptions regarding the form of URLs

Who is affected: Plug-ins which make assumptions regarding their installation structure, location and the local file system layout.

Description: Methods such as IPluginDescriptor.getInstallURL() return URLs of a particular form. Despite this form not being specified, various plug-ins make assumptions based on the current implementation. For example, they may expect to get a file: URL and use URL.getFile() and use java.io.File manipulation on the result. To date, this has been a workable but rather unsafe approach. For example, if a plug-in is installed on a web server, it is possible that an http: URL would be returned. The new Eclipse 3.0 runtime is even more flexible and opens more possibilities for execution configurations (e.g., maintaining whole plug-ins in JARs rather than exploded in directories). That is , while new runtime does not actually break 2.1 API, it exposes more cases where assumptions made in current plug-ins are invalid.

Action required: Plug-in writers should ensure that the information to which they need access is available via getResource() (and is on the classpath) or use the relevant API for accessing the contents of a plug-in (e.g., Bundle.getEntry(String)).

BootLoader API methods moved/deleted

Who is affected: Plug-ins which use certain API methods from the class org.eclipse.core.boot.BootLoader.

Description: Methods such as startup(), shutdown() and run() were moved from the BootLoader class (now supplied in the compatibility layer) to EclipseStarter which is part of the OSGi framework (i.e., org.eclipse.osgi). This API is the interface between the main() in startup.jar and the OSGi framework/Eclipse runtime. Given the restructuring of the runtime, these methods could not be left on BootLoader.

The method BootLoader.getRunnable() has been removed as the runtime can no longer support the acquisition of individual applications. Rather users should indicate the application of interest when they start the platform.

Action required: In general this API is used by very few people. In the rare case that it is, users can adapt by using the new methods on EclipseStarter.

Re-exporting runtime API

Who is affected: Plug-ins which expose API that includes elements from changed runtime API.

Description: Various plug-ins expose API that includes elements from the runtime API. With the changes to the Eclipse 3.0 runtime outlined here, client plug-ins must re-evaluate their use of runtime API in their API.

Action required: This scenario is quite quite rare are very little of the Eclipse runtime API is changing. Depending on the scenario, clients may have to change their API or continue to rely on the the compatibility layer.

Plug-in parsing methods on Platform

Who is affected: Users of org.eclipse.core.runtime.Platform.parsePlugins(..., Factory).

Description: The method org.eclipse.core.runtime.Platform.parsePlugins(..., Factory) has been moved. The API associated with the Factory argument has been moved from the org.eclipse.core.runtime plug-in up to the org.eclipse.core.runtime.compatibility plug-in (which depends on the runtime plug-in). As a result, the parsing method has been moved as well.

Action required: Users of this method should use the same method on the class org.eclipse.core.runtime.model.PluginRegistryModel.

Changes to build scripts

Who is affected: Developers maintaining scripts (e.g., Ant build.xml files) which define classpaths containing runtime related jars and class directories.

Description: The new runtime contains a number of new plug-ins and jars. Their introduction was mandated by the refactoring of the runtime into configurable pieces. For most runtime situations these changes are transparent. However, if you have custom build.xml (or similar) scripts which currently compile code against org.eclipse.core.runtime, you will need to update them before they will function correctly. A typical script contains a classpath entry in a <javac> task that references the org.eclipse.core.runtime plug-in as follows:

    ../org.eclipse.core.runtime/bin;../org.eclipse.core.runtime/runtime.jar

The runtime plug-in continues to contain much of the original runtime code. However, various parts of the runtime which are there only for compatibility purposes are contained in a compatibility plug-in (org.eclispe.core.runtime.compatibility). Most of the new runtime code is contained in a collection of plug-ins (org.eclipse.osgi.*).

Action required: Developers should add the entries below as needed to eliminate compilation errors. While the complete set of jars supplied is listed below, typical uses require only a subset on the classpath at compile time. As usual, the inclusion of the /bin directories is discretionary. The entries are given here in logical groupings by supplying plug-in:

In addition the following jars may be required in special cases:

While updating such scripts, you should also take the opportunity to clean up (i.e., remove) references to org.eclipse.core.boot. This plug-in is obsolete and longer contains any code. The entries can be left on the classpath but they serve no purpose and should be removed. Look to remove:

    ../org.eclipse.core.boot/bin;../org.eclipse.core.boot/boot.jar

Recommended Changes for 3.0

This section describes other changes that we recommend be made when porting an existing plug-in to 3.0.

Changes to API classes and interfaces (by package)

IWorkspaceRunnable and IWorkspace.run (org.eclipse.core.runtime)

Clients of the IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) method should revisit their uses of this method and consider using the richer method IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). The old IWorkspace.run method acquires a lock on the entire workspace for the duration of the IWorkspaceRunnable. This means that an operation done with this method will never be able to run concurrently with other operations that are changing the workspace. In Eclipse 3.0, many long-running operations have been moved into background threads, so the likelihood of conflicts between operations is greatly increased. If a modal foreground operation is blocked by a long running background operation, the UI becomes blocked until the background operation completes, or until one of the operations is canceled.

The suggested solution is to switch all references to old IWorkspace.run to use the new method with a scheduling rule parameter. The scheduling rule should be the most fine-grained resource that encompasses all changes by that operation. If desired, a MultiRule can be used to specify multiple resource rules. If the operation tries to modify resources outside of the scope of the scheduling rule, a runtime exception will occur. The following table summarizes what scheduling rule is required for each of the different types of resource operations:

Type of operation Rule required
Create, modify, or delete file or folder Parent resource
Create, delete, open or close project Project
Change project description Workspace root
Refresh local Resource
Create, delete, or modify marker null
Create, delete or modify sync info Resource
Build workspace or project Workspace root

IWorkbenchPage (package org.eclipse.ui)

IEditorDescriptor (package org.eclipse.ui)

ISharedImages (package org.eclipse.ui)

IWorkbenchActionConstants (package org.eclipse.ui)

IWorkbenchPreferenceConstants (package org.eclipse.ui)

IExportWizard (package org.eclipse.ui)

IImportWizard (package org.eclipse.ui)

INewWizard (package org.eclipse.ui)

WorkbenchHelp (package org.eclipse.ui.help)

IHelp (package org.eclipse.help)

ITextEditorActionConstants (package org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (package org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (package org.eclipse.ui.texteditor)

TextEditorActionContributor (package org.eclipse.ui.editors.text)

ILaunchConfigurationType (package org.eclipse.debug.core)

With the introduction of extensible launch modes in 3.0, more than one launch delegate can exist for a launch configuration type. Releases prior to 3.0 only supported one launch delegate per launch configuration type. The method ILaunchConfigurationType.getDelegate() is now deprecated. The method getDelegate(String mode) should be used in its place to retrieve the launch delegate for a specific launch mode. The deprecated method has been changed to return the launch delegate for the run mode.

ILaunchConfigurationTab and ILaunchConfigurationTabGroup (package org.eclipse.debug.ui)

Launch tab groups and launch tabs are no longer notified when a launch completes. The method launched(ILaunch) in the interfaces ILaunchConfigurationTab and ILaunchConfigurationTabGroup has been deprecated and is no longer called. Relying on this method for launch function was always problematic, since tabs only exist when launching is performed from the launch dialog. Also, with the introduction of background launching, this method can no longer be called, as the launch dialog is be closed before the resulting launch object exists.

ILaunchConfigurationTab and AbstractLaunchConfigurationTab (package org.eclipse.debug.ui)

Two methods have been added to the ILaunchConfigurationTab interface - activated and deactivated. These new life cycle methods are called when a tab is entered and exited respectively. Existing implementations of ILaunchConfigurationTab that subclass the abstract class provided by the debug plug-in (AbstractLaunchConfigurationTab) are binary compatible since the methods are implemented in the abstract class.

In prior releases, a tab was sent the message initializeFrom when it was activated, and performApply when it was deactivated. In this way, the launch configuration tab framework provided inter-tab communication via a launch configuration (by updating the configuration with current attribute values when a tab is exited, and updating the newly entered tab). However, since many tabs do not perform inter-tab communication, this can be inefficient. As well, there was no way to distinguish between a tab being activated, and a tab displaying a selected launch configuration for the first time. The newly added methods allow tabs to distinguish between activation and initialization, and deactivation and saving current values.

The default implementation of activated, provided by the abstract tab, calls initializeFrom. And, the default implementation of deactivated calls performApply. Tabs wishing to take advantage of the new API should override these methods as required. Generally, for tabs that do not perform inter-tab communication, the recommended approach is to re-implement these methods to do nothing.

launchConfigurationTabGroup extension point Type (package org.eclipse.debug.ui)

In prior releases, perspective switching was specified on a launch configuration, via the launch configuration attributes ATTR_TARGET_DEBUG_PERSPECTIVE and ATTR_TARGET_RUN_PERSPECTIVE. With the addition of extensible launch modes in 3.0, this approach no longer scales. Perspective switching is now specified on launch configuration type basis, per launch mode that a launch configuration type supports. API has been added to DebugUITools to set and get the perspective associated with a launch configuration type for a specific launch mode.

An additional, optional, launchMode element has been added to the launchConfigurationTabGroup extension point, allowing a contributed tab group to specify a default perspective for a launch configuration type and mode.

From the Eclipse user interface, users can edit the perspective associated with a launch configuration type by opening the launch configuration dialog, and selecting a launch configuration type node in the tree (rather than an individual configuration). A tab is displayed allowing the user to set a perspective with each supported launch mode.

[JDT only] IVMRunner (package org.eclipse.jdt.launching)

Two methods have been added to the VMRunnerConfiguration class to support the setting and retrieving of environment variables. Implementors of IVMRunner should call VMRunnerConfiguration.getEnvironment() and pass that environment into the executed JVM. Clients who use DebugPlugin.exec(String[] cmdLine, File workingDirectory) can do this by calling DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp) instead. Simply passing in the result from getEnvironment() is sufficient.

[JDT only] VMRunnerConfiguration and Bootstrap Classes (package org.eclipse.jdt.launching)

In prior releases, the VMRunnerConfiguration had one attribute to describe a boot path. The attribute is a collection of Strings to be specified in the -Xbootclasspath argument. Three new attributes have been added to the VMRunnerConfiguration to support JVMs that allow for prepending and appending to the boot path. The new methods/attributes added are:

The old attribute, getBootClassPath(), still exists and contains a complete path equivalent to that of the three new attributes. However, VMRunners that support the new boot path options should take advantage of the new attributes.

[JDT only] Improved support for working copies (package org.eclipse.jdt.core)

The Java model working copy facility has been reworked in 3.0 to provide greatly increased functionality. Prior to 3.0, the Java model allowed creation of individual working copies of compilation units. Changes could be made to the working copy and later committed. There was support for limited analysis of a working copy in the context of the rest of the Java model. However, there was no way these these analyses could ever take into account more than one of the working copies at a time.

The changes in 3.0 make it possible to create and manage sets of working copies of compilation units, and to perform analyses in the presence of all working copies in a set. For example, it is now possible for a client like JDT refactoring to create working copies for one or more compilation units that it is considering modifying and then to resolve type references between the working copies. Formerly this was only possible after the changes to the compilation unit working copies had been committed.

The Java model API changes in 2 ways to add this improved support:

(1) The functionality formerly found on IWorkingCopy and inherited by ICompilationUnit has been consolidated into ICompilationUnit. The IWorkingCopy interface was only used in this one place, and was gratuitously more general that in needed to be. This change simplifies the API. IWorkingCopy has been deprecated. Other places in the API where IWorkingCopy is used as a parameter or result type have been deprecated as well; the replacement API methods mention ICompilationUnit instead of IWorkingCopy.

(2) The interface IBufferFactory has been replaced by WorkingCopyOwner. The improved support for working copies requires that there be an object to own the working copies. Although IBufferFactory is in the right place, the name does not adequately convey how the new working copy mechanism works. WorkingCopyOwner is much more suggestive. In addition, WorkingCopyOwner is declared as an abstract class, rather than as an interface, to allow the notion of working copy owner to evolve in the future. The one method on IBufferFactory moves to WorkingCopyOwner unaffected. WorkingCopyOwner does not implement IBufferFactory to make it clear that IBufferFactory is a thing of the past. IBufferFactory has been deprecated. Other places in the API where IBufferFactory appears as a parameter or result type have been deprecated as well; the replacement API methods mention WorkingCopyOwner instead of IBufferFactory.

These changes do not break binary compatibility.

When migrating, all references to the type IWorkingCopy should instead reference ICompilationUnit. The sole implementation of IWorkingCopy implements ICompilationUnit as well, meaning objects of type IWorkingCopy can be safely cast to ICompilationUnit.

A class that implements IBufferFactory will need to replaced by a subclass of WorkingCopyOwner. Although WorkingCopyOwner does not implement IBufferFactory itself, it would be possible to declare the subclass of WorkingCopyOwner that implements IBufferFactory thereby creating a bridge between old and new (IBufferFactory declares createBuffer(IOpenable) whereas WorkingCopyOwner declares createBuffer(ICompilationUnit); ICompilationUnit extends IOpenable).

Because the changes involving IWorkingCopy and IBufferFactory are interwined, we recommend dealing with both at the same time. The details of the deprecations are as follows:

Restructuring of org.eclipse.help plug-in

The org.eclipse.help plug-in, which used to hold APIs and extension points for contributing to and extending help system, as well as displaying help, now contains just APIs and extension points for contributing and accessing help resources. A portion of default help UI implementation contained in that plug-in has been moved to a new plug-in org.eclipse.help.base together with APIs for extending the implementation. The APIs and extension point for contributing Help UI and displaying help have been moved to org.eclipse.ui plug-in. This restructuring allows applications greater flexibility with regard to the help system; the new structure allows applications based on the generic workbench to provide their own Help UI and/or Help implementation, or to omit the help system entirely.

Because the extension points and API packages affected are intended only for use by the help system itself, it is unlikely that existing plug-ins are affected by this change. They are included here only for the sake of completeness:

null messages in MessageBox and DirectoryDialog (package org.eclipse.swt.widgets)

Prior to 3.0, calling SWT's DirectoryDialog.setMessage(String string) or MessageBox.setMessage(String string) with a null value for string would result in a dialog with no text in the title. This behavior was unspecified (passing null has never been permitted) and creates problems with getMessage which is not permitted to return null. In 3.0, passing null now results in an IllegalArgumentException exception being thrown, and the specifications have been changed to state this, bringing it into line with the method on their superclass Dialog.setMessage. If you use Dialog.setMessage, ensure that that the string passed in is never null. Simply pass an empty string if you want a dialog with no text in the title.

Proposed Changes for 3.0

The following proposals are under discussion for inclusion in Eclipse 3.0. They are mentioned here because the proposed changes impact existing plug-ins being ported to 3.0.

PDE Plug-in Migration Tool

PDE provides a special wizard for converting 2.1 plug-in manifest to 3.0, found at PDE Tools > Migrate to 3.0. on the context menu for the selected plugin.xml or fragment.xml file. In addition to adding <?eclipse ...?> line, this migration tool also fixes up references to the extension points that have been renamed and changes the plug-ins dependencies list to reflect the Platform restructuring.

General Information on Compatibility

Eclipse 3.0 is not fully compatible with 2.0 and 2.1. The nature and scope of some of the key 3.0 plan items were such that the only feasible solutions break compatibility. The decision to make these breaking changes was done after open discussion with the community. That said, most of the Eclipse APIs are the same in 3.0 as in 2.1 and 2.0. We have only broken APIs in 3.0 when there is a compelling case for doing so, and have tried to do it in a controlled way that minimizes the effort required to port an existing plug-in to the 3.0 APIs. Furthermore, in order to ensure that existing 2.1 binary plug-ins in the field continue to run with 3.0 despite these breaking change, we have included additional runtime compatibility mechanisms to provide effective binary API compatibility.

API Contract Compatibility: Eclipse SDK 3.0 is upwards contract-compatible with Eclipse SDK 2.0 and 2.1 except in those areas noted in this document. Programs that use affected APIs and extension points will need to be ported to Eclipse SDK 3.0 APIs (API is construed broadly to include such things as plug-in extension points.) Downward contract compatibility is not supported. There is no guarantee that compliance with Eclipse SDK 3.0 APIs would ensure compliance with Eclipse SDK 2.0 or 2.1 APIs. Refer to Evolving Java-based APIs for a discussion of the kinds of API changes that maintain contract compatibility.

Binary (plug-in) Compatibility: Eclipse SDK 3.0 is upwards binary-compatible with Eclipse SDK 2.0 and 2.1 except in those areas noted in this document. Eclipse 3.0 includes additional runtime compatibility mechanisms to provide effective binary API compatibility. For cases not covered by these runtime compatibility mechanisms, plug-ins that use affected APIs and extension points will need to be ported and recompiled for Eclipse SDK 3.0. Downward plug-in compatibility is not supported either. Plug-ins for Eclipse SDK 3.0 will not be usable in Eclipse SDK 2.0 or 2.1. Refer to Evolving Java-based APIs for a discussion of the kinds of API changes that maintain binary compatibility.

Source Compatibility: Eclipse SDK 3.0 is upwards source-compatible with Eclipse SDK 2.0 or 2.1 except in the areas noted in this document. This means that source files written to use Eclipse SDK 2.0 or 2.1 APIs might successfully compile and run against Eclipse SDK 3.0 APIs, although this is not guaranteed. Downward source compatibility is not supported. If source files use new Eclipse SDK APIs, they will not be usable with an earlier version of the Eclipse SDK.

Workspace Compatibility: Eclipse SDK 3.0 is upwards workspace-compatible with Eclipse SDK 2.0 or 2.1 unless noted. This means that workspaces and projects created with Eclipse SDK 2.0 or 2.1 can be successfully opened by Eclipse SDK 3.0 and upgraded to a 3.0 workspace. This includes both hidden metadata, which is localized to a particular workspace, as well as metadata files found within a workspace project (e.g., the .project file), which may propagate between workspaces via file copying or team repositories. Individual plug-ins developed for Eclipse SDK 3.0 should provide similar upwards compatibility for their hidden and visible workspace metadata created by earlier versions; 3.0 plug-in developers are responsible for ensuring that their plug-ins recognize 3.0, 2.1, and 2.0 metadata and process it appropriately. User interface session state may be discarded when a workspace is upgraded. Downward workspace compatibility is not supported. A workspace created (or opened) by Eclipse SDK 3.0 will be unusable with an earlier version of Eclipse SDK. Visible metadata files created (or overwritten) by Eclipse SDK 3.0 will generally be unusable with earlier versions of Eclipse SDK.

Non-compliant usage of API's: All non-API methods and classes, and certainly everything in a package with "internal" in its name, are considered implementation details which may vary between operating environment and are subject to change without notice. Client plug-ins that directly depend on anything other than what is specified in the Eclipse SDK API are inherently unsupportable and receive no guarantees about compatibility within a single release much less with an earlier releases. Refer to How to Use the Eclipse API for information about how to write compliant plug-ins. This porting guide does not cover non-API methods and classes.

Copyright IBM Corporation and others 2000, 2004.