| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | |
| <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]"> | |
| <meta name="Author" content="Jim des Rivières"> | |
| <title>API Rules of Engagement</title> | |
| <link rel="stylesheet" href="../article.css"> | |
| </head> | |
| <body> | |
| <h1>How to Use the Eclipse API</h1> | |
| <div class="summary"> | |
| <h2>Summary</h2> | |
| <p>The Eclipse Platform offers a comprehensive API (Application | |
| Programmer Interface) to developers writing plug-ins. This article | |
| discusses the general ground rules for using the Eclipse Platform API, | |
| including how to tell API from non-API, and how to stay in the API | |
| "sweet spot" to avoid the risk of being broken as the platform and its | |
| APIs evolve. These general ground rules are also recommended practice | |
| for plug-ins that must declare API elements of their own.</p> | |
| <div class="author">By Jim des Rivières, OTI</div> | |
| <div class="copyright">Copyright © 2001 Object Technology | |
| International, Inc.</div> | |
| <div class="date">Updated May 18, 2001</div> | |
| </div> | |
| <div class="content"> | |
| <h3>What it means to be API</h3> | |
| <p>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.</p> | |
| <h3>How to tell API from non-API</h3> | |
| <p>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.</p> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>API package</b> - a Java™ package that contains at | |
| least one API class or API interface. The names of API packages are | |
| advertised in the documentation for that component; where feasible, all | |
| other packages containing only implementation details have "internal" | |
| in the package name. The names of API packages may legitimately appear | |
| in client code. For the Eclipse platform proper, these are:</li> | |
| <ul> | |
| <li><tt>org.eclipse.foo.*</tt> - for example, <tt>org.eclipse.swt.widgets</tt>, | |
| <tt>org.eclipse.ui</tt>, or <tt>org.eclipse.core.runtime</tt></li> | |
| <li><tt>org.eclipse.foo.internal.*</tt> - not API; internal | |
| implementation packages</li> | |
| <li><tt>org.eclipse.foo.examples.*</tt> - not API; these are | |
| examples</li> | |
| <li><tt>org.eclipse.foo.tests.*</tt> - not API; these are test | |
| suites</li> | |
| </ul> | |
| <li><b>API class or interface</b> - a <tt>public</tt> class or | |
| interface in an API package, or a <tt>public</tt> or <tt>protected</tt> | |
| class or interface member declared in, or inherited by, some other API | |
| class or interface. The names of API classes and interfaces may | |
| legitimately appear in client code.</li> | |
| <li><b>API method or constructor</b> - a <tt>public</tt> or <tt>protected</tt> | |
| method or constructor either declared in, or inherited by, an API class | |
| or interface. The names of API methods may legitimately appear in | |
| client code.</li> | |
| <li><b>API field</b> - a <tt>public</tt> or <tt>protected</tt> | |
| field either declared in, or inherited by, an API class or interface. | |
| The names of API fields may legitimately appear in client code.</li> | |
| </ul> | |
| <p>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:</p> | |
| <ul> | |
| <li><b>Stick to officially documented APIs. </b>Only reference | |
| packages that are documented in the <b><i>published API Javadoc</i></b> | |
| for the component. Never reference a package belonging to another | |
| component that has "internal" in its name---these are never API. Never | |
| reference a package for which there is no published API Javadoc---these | |
| are not API either.</li> | |
| </ul> | |
| <h3>General Rules</h3> | |
| <p>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:</p> | |
| <ul> | |
| <li><b>Honor all contracts.</b> The contracts are described in the | |
| published Javadoc for the API elements you are using.</li> | |
| </ul> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>You must honor "must". </b>Pay especially close heed to | |
| conditions where "must" is used.</li> | |
| </ul> | |
| <p>Other common sense rules:</p> | |
| <ul> | |
| <li><b>Do not rely on incidental behavior. </b>Incidental behavior | |
| is behavior observed by experiment or in practice, but which is not | |
| guaranteed by any API specification.</li> | |
| <li><b>Do not treat null as an object.</b> Null is more the lack | |
| of an object. Assume everything is non-null unless the API | |
| specification says otherwise.</li> | |
| <li><b>Do not try to cheat with Java reflection.</b> Using Java | |
| reflection to circumvent Java compiler checking buys you nothing more. | |
| There are no additional API contracts for uses of reflection; | |
| reflection simply increases the likelihood of relying on unspecified | |
| behavior and internal implementation detail.</li> | |
| <li><b>Use your own packages. </b>Do not declare code in a package | |
| belonging to another component. Always declare your own code in your | |
| own packages.</li> | |
| </ul> | |
| <h3>Calling public API methods</h3> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>Ensure preconditions.</b> Do ensure that an API method's | |
| preconditions are met before calling the method. Conversely, the caller | |
| may safely assume that the method's postconditions will have been | |
| achieved immediately upon return from the call.</li> | |
| <li><b>Null parameters.</b> Do not pass null as a parameter to an | |
| API method unless the parameter is explicitly documented as allowing | |
| null. This is perhaps the most frequently made programming error.</li> | |
| <li><b>Restricted callers.</b> Do not call an API method that is | |
| documented as available only to certain callers unless you're one of | |
| them. In some situations, methods need to be part of the public API for | |
| the benefit of a certain class of callers (often internal); calling one | |
| of these methods at the wrong time has unspecified (and perhaps | |
| unpredictable) consequences.</li> | |
| <li><b>Debugging methods.</b> Do not call an API method labelled | |
| "for debugging purposes only". For example, most <tt>toString()</tt> | |
| methods are in this category.</li> | |
| <li><b>Parameter capture.</b> Do not pass an array, collection, or | |
| other mutable object as a parameter to an API method and then modify | |
| the object passed in. This is just asking for trouble.</li> | |
| </ul> | |
| <h3>Instantiating platform API classes</h3> | |
| <p>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 <tt>dispose()</tt> 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.").</p> | |
| <ul> | |
| <li><b>Restricted instantiators.</b> Do not instantiate an API | |
| class that is documented as available only to certain parties unless | |
| you're one of them. In some situations, classes need to be part of the | |
| public API for the benefit of a certain party (often internal); | |
| instantiating one of these classes incorrectly has unspecified (and | |
| perhaps unpredictable) consequences.</li> | |
| </ul> | |
| <h3>Subclassing platform API classes</h3> | |
| <p>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.").</p> | |
| <ul> | |
| <li><b>Restricted subclassers.</b> Do not subclass an API class | |
| that is not intended to be subclassed. Treat these classes as if they | |
| had been declared final. (These are sometimes referred to as "soft | |
| final" classes).</li> | |
| </ul> | |
| <h3>Calling protected API methods</h3> | |
| <p>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.</p> | |
| <h3>Overriding API methods</h3> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>Do not override a public or protected API method unless | |
| it is explicitly allowed.</b> Unless otherwise indicated, treat all methods | |
| as if they had been declared final. (These are sometimes known as "soft | |
| final" methods). If the kind of overriding allowed is:</li> | |
| <ul> | |
| <li>"<b>implement</b>" | |
| - the abstract method declared on the subclass must be implemented | |
| by a concrete subclass</li> | |
| <li> | |
| "<b>extend</b>" - the method declared on the subclass must invoke the method on the | |
| superclass (exactly once)</li> | |
| <li> | |
| "<b>re-implement</b>" - the method declared on the subclass must not invoke the method on | |
| the superclass</li> | |
| <li> | |
| "<b>override</b>" - the method declared on the subclass is free to invoke the method | |
| on the superclass as it sees fit</li> | |
| </ul> | |
| <li><b>Ensure postconditions. </b>Do ensure that any | |
| postconditions specified for the API method are met by the | |
| implementation upon return.</li> | |
| <li><b>Proactively check preconditions. </b>Do not presume that | |
| preconditions specified for the API method have necessarily been met | |
| upon entry. Although the method implementation would be within its | |
| rights to not check specified preconditions, it is usually a good idea | |
| to check preconditions (when feasible and reasonably inexpensive) in | |
| order to blow the whistle on misbehaving callers.</li> | |
| <li><b>Null result. </b>Do not return null as a result from an API | |
| method unless the result is explicitly documented (on the specifying | |
| interface or superclass) as allowing null.</li> | |
| <li><b>Return copies. </b>Do not return an irreplaceable array, | |
| collection, or other mutable object as the result from an API method. | |
| Always return a copy to avoid trouble from callers that might modify | |
| the object.</li> | |
| </ul> | |
| <h3>Implementing platform API interfaces</h3> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>Restricted implementors.</b> Do not implement an API | |
| interface that is documented as available only to certain parties | |
| unless you're one of them. In many situations, interfaces are used to | |
| hide internal implementation details from view.</li> | |
| </ul> | |
| <h3>Implementing public API methods</h3> | |
| <p>See "Overriding API methods".</p> | |
| <h3>Accessing Fields in API classes and interfaces</h3> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>Null fields.</b> Do not set an API field to null unless | |
| this is explicitly allowed.</li> | |
| </ul> | |
| <h3>Casting Objects of a known API type</h3> | |
| <p>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.</p> | |
| <ul> | |
| <li><b>Cast and instanceof.</b> Do not use instanceof and cast | |
| expressions to increase what is known about an object beyond what the | |
| API supports. Improper use exposes incidental implementation details | |
| not guaranteed by the API.</li> | |
| </ul> | |
| <p>And, of course, casting any object to a non-API class or interface is | |
| always inappropriate.</p> | |
| <h3>Not Following the Rules</h3> | |
| <p>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.</p> | |
| <p>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."</p> | |
| <p>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.</p> | |
| </div> | |
| <div class="notices"><p>Java and all Java-based trademarks and logos | |
| are trademarks or registered trademarks of Sun Microsystems, Inc. in the | |
| United States, other countries, or both.</p></div> | |
| </body> | |
| </html> |