WTP API Policy
WTP API Policy
In previous releases WTP did not have enough API to meet our adopter's needs and was causing repeated breakage to adopters as we changed our internal code. This led to the adoption of an internal usage scan policy - if an adopter was willing to supply usage data for WTP, we agreed not to change any of the internal code used by the adopter.
This policy was required at the time to stabilize WTP and encourage widespread adoption. However, continuing this policy indefinitely hampers innovation in WTP and makes it difficult to create API. This document provides a new API policy that will allow us to innovate while still encouraging widespread adoption.
Declared API is public API that WTP has committed to supporting for several releases. It should be clean and contain adequate javadoc.
New API must be approved by the component or subproject lead. Declared API may evolve in the first few milestones, but it must be frozen by the release API freeze date and will not change throughout the remainder of the release or the corresponding maintenance releases.
Declared API should have at least two clients or known adopters, at least one of which must be public as part of WTP (or another Eclipse Project). In some cases it is acceptable for the client to be a sample or example instead of full fledged end-user functionality.
In following releases, API may sometimes be deprecated due to the normal evolution of WTP. Deprecations must be approved by the project lead and must contain information on a migration path for existing adopters. Deprecated API may not be removed for at least 2 major releases (and preferably longer), and after notifying the community. Exceptions must be approved by the PMC.
Provisional API is a work in progress towards fully Declared API and can be used when committers want to gather community feedback before declaring API, or when there are known problems with a new API that cannot be addressed by API freeze date. Provisional API status is meant to be a temporary state and API should not remain provisional for an undue length of time.
Committers should avoid creating Provisional API in any package that would not be appropriate for the final Declared API. This includes package names that use words such as "internal" or "provisional". Labeling existing internal code as provisional is allowed in order to declare a greater degree of support to potential adopters, but committers should exercise care when using this option.
Provisional API should be marked at the class or member level with the following javadoc comment:
- * Provisional API: This class/interface is part of an interim API that is still under development and expected to
- * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
- * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
- * (repeatedly) as the API evolves.
New provisional API must be approved by the component or subproject lead. Due to the risk of stagnation or over-use, leads should ensure that the use is appropriate (e.g. is it ready for feedback? why can't it be declared as API instead?) and that we have a plan for evolution in the subsequent release. A bugzilla must be opened (using "[API]" in the Summary and "provisional" in the Whiteboard) to track the evolution of this code in the following release.
Provisional API may evolve during the first milestones but it must be frozen by the regular API freeze date of a release and will not change for the remainder of the release and the corresponding maintenance releases. Exceptions must be approved by the PMC.
Provisional API should not stagnate. It may be declared as API, undergo extensive change, or be removed at any time in following releases. No approval is necessary, but we strongly recommend that committers notify the community of changes.
Protected Non-API Usage
Protected Non-API usage are internal methods that have been reported in adopter usage scans and WTP has agreed to maintain. This may include use of Provisional API, which is covered by this category.
As of Feb 29th, 2008, WTP will no longer accept new internal usage scans. We will continue to respect the latest usage scan from all adopters received before Feb 29th.
During regular development milestones committers must send a note to the mailing list and to the email address listed in any affected adopter scan 2 (two) weeks before making any breaking change to protected internal usage. The note should include information on what is changing, potential migration paths, if there is a deprecation period, etc. If there is no response within the two weeks or all responses are positive, the committer is free to make the change.
If any adopters object to the change, the committer must work with them to find an acceptable solution. Some possibilities are more information about the change, providing a deprecation period, changing the timing, or additional information to help with porting. If the adopters agree after this discussion, the committer can go ahead with the change.
If the committer and adopters cannot find a reasonable compromise, the issue will be brought to the PMC for arbitration. The PMC may decide on any solution it feels balances between supporting the adopter community as a platform and allowing innovation and change in WTP.
Protected Non-API usage may not change after the regular API freeze date of a release and will be treated like declared API for the remainder of the release and the corresponding maintenance releases.
There are several opportunities for code to evolve out of protected Non-API usage:
- Declare as API or declare an equivalent API.
- Provide Provisional API.
- Illegitimate non-API usage - If the code is deemed illegitimate internal use, the adopter will be notified and the use will be removed (unprotected) from the usage scans. In cases where the usage is questionable, a committer may question the adopter on why the internal code is being used. If the use is not acceptable after a reasonable discussion, it may become unprotected.
- The following are some examples of illegitimate internal usage:
- Use of messages, icons, logging or tracing methods from another plugin.
- Use of internal methods where equivalent API exists. (In cases where new API is declared, reasonable time should be given for porting)
- Use of internal utility classes unrelated to the purpose of the plugin.
- The following are some examples of illegitimate internal usage:
- Adopter agreement - If the adopter no longer needs it or code dependencies are minimal, the adopter may agree to remove or reduce the protected internal usage scans.
- Project graduation - If a WTP project has well defined API and minimal internal usage, it may request 'graduation' from the PMC from the protected internal use policy.
Any code covered in the illegitimate non-API usage, removed by adopter agreement, or project graduation categories will be treated like regular internal use described below.
Any protected non-API use that has not evolved in one of these directions after two releases (WTP '4.0') will default to declared API, and WTP projects will have to follow regular declared API rules (e.g. deprecation) when changing this code. At that time this section of the API policy will be removed.
Internal code is everything else - usually indicated by 'internal' in the package or extension point name, or tagged as 'x-internal' in a manifest file. WTP reserves the right to change internal code at any time.
If adopters require the use of internal code and do not want to be continually broken, they should open bugzilla enhancement requests for API. These bugs will be triaged and will help drive the creation of new declared or provisional API.
Due to the risk that we may break an adopter we will attempt to not to change any internal code that is accessible by adopters (i.e. internal public and protected classes and methods) in maintenance releases. However, as in any internal code we reserve the right to make changes at any time.
How to provide, and consume version numbers
For the most part, we follow the versioning guidelines in common use. But those guidelines don't explicitly cover provisional or protected (non) API.
For provisional and even protect (non) API, please threat the bundle (or package) versioning scheme as though it was internal non-API. For example, you should not increment the major field of a version number, just because the provisional or protected API changes from one release to another. Use the minor field instead. Changing the major field would be much more "breaking" than the change in provisional API, and we want to reserve that major field for official API breaking changes.
This policy means it is critical for adopters to specify narrow ranges in bundle pre-reqs whenever they use provisional API or protected non-API. That narrow range ensures they will not accidentally get a subsequent, higher versioned bundle that has changes in the provisional API.
WTP consists of several projects, most of which depend on several other projects both internal and external to WTP. As WTP and the individual projects continue to grow, it is important that we have a plan to deal with dependencies between each of these projects.
For the purposes of this discussion, a project is not necessarily a small enough boundary. We need to define the vague notion of a 'component' as a set of plugins. They may be contained in a single project or feature, or you can think of them as a set of plugins that could be shipped or updated independently from the rest of WTP, but neither of these need to be the case.
Every project consists of at least one component. Projects that cross the "WST/JST" boundary will contain at least two, and in some projects there may be additional components based on the natural split of function. A set of plugins that have a core and UI split or separate help plugins are typically still a single component.
As an example, the server tools project consists of at least three natural components: the WST server framework, the JST server extensions for Java EE, and one or more components containing exemplary server adapters.
Use of x-friends and x-internal
Within a component, x-friends can be used in the manifest to give 'internal' access to any plugin that requires it. x-friends should never be used across component boundaries.
Likewise, x-internal should be used on all packages that should not be used as API outside of the component.
It's clear that WTP does not currently follow this practice. However, since we do not have independent builds or releases planned anytime soon for WTP projects or components, enforcement of these practices is not critical. We readily see breaks between components in our build, and can negotiate among ourselves to resolve it.
Clean API use is encouraged, and where feasible "API request" bugs should be opened between components just as we expect from others. Since this is not a high priority there will be no short term focused effort to make sure that it is done, but it's our intention to clean up our inter-component API usage over time.
For more information, please see WTP Policy on Package Visibility