Eclipse platform
API rules of engagement

Version 0.15 - Last revised 12:00 May 30, 2001

Here are the rules of engagement for clients of the Eclipse platform API (and other components).

What it means to be API

The Eclipse platform defines API elements for use by its clients, namely ISVs writing plug-ins. These plug-ins may in turn define API elements for their clients, and so on. API elements are the public face: they carry a specification about what they are supposed to do, and about how they are intended to be used. API elements are supported: the Eclipse platform team will fix implementation bugs where there is a deviation from the specified behavior. Since there is often a high cost associated with breaking API changes, the Eclipse platform team will also try to evolve API elements gracefully through successive major releases.

How to tell API from non-API

By their very nature, API elements are documented and have a specification, in contrast to non-API elements which are internal implementation details usually without published documentation or specifications. So if you cannot find the documentation for something, that's usually a good indicator that it's not API.

To try to draw the line more starkly, the code base for the platform is separated into API and non-API packages, with all API elements being declared in designated API packages.

Everything else is considered internal implementation detail and off limits to all clients. Legitimate client code must never reference the names of non-API elements (not even using Java reflection). In some cases, the Java language's name accessibility rules are used to disallow illegal references. However, there are many cases where this is simply not possible. Observing this one simple rule avoids the problem completely:

General rules

The specification of API elements is generated from Javadoc comments in the element's Java source code. For some types of elements, the specification is in the form of a contract. For example, in the case of methods, the contract is between two parties, the caller of the method and the implementor of the method. The fundamental ground rule is: The term "must", when used in an API contract, means that it is incumbent on the party to ensure that the condition would always be met; any failure to do so would be considered a programming error with unspecified (and perhaps unpredictable) consequences. Other common sense rules:

Calling public API methods

For most clients, the bulk of the Eclipse API takes the form of public methods on API interfaces or classes, provided for the client to call when appropriate.

Instantiating platform API classes

Not all concrete API classes are intended to be instantiated by just anyone. API classes have an instantiation contract indicating the terms under which instances may be created. The contract may also cover things like residual initialization responsibilities (for example, configuring a certain property before the instance is fully active) and associated lifecycle responsibilities (for example, calling dispose() to free up OS resources hung on to by the instance). Classes that are designed to be instantiated by clients are explicitly flagged in the Javadoc class comment (with words like "Clients may instantiate.").

Subclassing platform API classes

Only a subset of the API classes were designed to be subclassed. API classes have a subclass contract indicating the terms under which subclasses may be declared. This contract also covers initialization responsibilities and lifecycle responsibilities. Classes that are designed to be subclassed by clients are explicitly flagged in the Javadoc class comment (with words like "Clients may subclass.").

Calling protected API methods

Calling inherited protected and public methods from within a subclass is generally allowed; however, this often requires more care to correctly call than to call public methods from outside the hierarchy.

Overriding API methods

Only a subset of the public and protected API methods were designed to be overridden. Each API method has a subclass contract indicating the terms under which a subclass may override it. By default, overriding is not permitted. It is important to check the subclass contract on the actual method implementation being overridden; the terms of subclass contracts are not automatically passed along when that method is overridden.

Implementing platform API interfaces

Only a subset of the API interfaces were designed to be implemented by clients. API interfaces have a contract indicating the terms under which it may be implemented. Interfaces that are designed to be implemented by clients are explicitly flagged in the Javadoc class comment (with words like "Clients may implement."). A client may declare a subinterface of an API interface if and only if they are allowed to implement it.

Implementing public API methods

See "Overriding API methods".

Accessing fields in API classes and interfaces

Clients may read API fields, most of which are final. Certain struct-like objects may have non-final public fields, which clients may read and write unless otherwise indicated.

Casting objects of a known API type

An object of a known API type may only be cast to a different API type (or conditionally cast using instanceof) if this is explicitly allowed in the API.

And, of course, casting any object to a non-API class or interface is always inappropriate.

Not following the rules

Whether done knowingly or unwittingly, there are consequences for transgressing the rules. It might be easier for all involved if there were API police that would bust you for breaking the rules. However, that is not the case. For the most part, API conformance operates as an honor system, with each client responsible for knowing the rules and adhering to them.

The contracts on the API elements delimit the behavior that is supported and sustained. As the Eclipse platform matures and evolves, it will be the API contracts that guide how this evolution happens. Outside of these contracts, everything is unsupported and subject to change, without notice, and at any time (even mid-release or between different OS platforms). Client code that oversteps the above rules might fail on different versions and patch levels of the platform; or when run on different underlying OSes; or when run with a different mix of co-resident plug-ins; or when run with a different workbench perspective; and so on. Indeed, no one is even particularly interested in speculating exactly how any particular transgression might come back to bite you. To those who choose to ignore the rules, don't say that you weren't warned. And don't expect much more than a sympathetic "Told you so."

On the other hand, client plug-in code that lives by the above rules should continue to work across different versions and patch levels of the platform, across different underlying OSes, and should peacefully co-exist with other plug-ins. If everyone plays by the rules, the Eclipse platform will provide a stable and supported base on which to build exciting new products.