WTP Policy on Package Visibility
THIS IS A DRAFT DOCUMENT UNDER REVIEW
In contrast to the Eclipse Platform's policy of always having complete package visibility expressed in bundle's manifest.mf files, we in WTP believe there are some cases it is not necessary to require sub-projects or components to have all packages visible. We believe it may be easier and cheaper for committers to not even risk others using that sort of very internal package. On the flip side, though, there is more obligation and responsibility for committers to provide good API for any functionality that is not visible. This is simply a matter of good design ... which we want to encourage ... much like the use of private variables, final classes, and packages with default (package only) Java visibility. Further, we believe long term, it will make for a better platform, since it forces us to "stay honest", and since it can made clear what's API and what is not (that is, it's self documenting) especially since we in WTP also have a fuzzy non-API but which we know adopters use (and won't break those adopters without some warning or discussion). Also, we hope this will improve communication between adopters and committers in that if adopters do need to use something that's internal, then it may be that we have not well documented how to do it via API, or perhaps we have missed some requirement that we should know about and implement.
But, to adopt this policy successfully, without impacting our work, and without impacting any adopters, there are some strict rules that have to be followed.
- The only packages that can be made "hidden" are ones that no known adopter currently uses (known from our adopter usage scans) and that no one in WTP currently uses, even test plugins. [There may be ways for tests to use normally non-visible implementations through the use of test-time-only fragments, but that's for Eclipse Graduate school :) and will be left as an exercise for the reader.]
- Developers should not spend a lot of time or effort making just to make things hidden, as that process itself might break our own code or adopters. The idea is to start with the easy and obvious cases and see how it goes: see how it's accepted, see how we like working with it.
- Having package's hidden must never override the need for JUnit tests. If you can not adequately test an implementation through exposed packages, then the JUnits come first ... better to have code tested well, than to have it hidden (though, should still be marked as "x-friend").
- If any adopter requests something be made visible, via a bugzilla entry, our inclination must always be to say "sure we will, since we are adopter friendly". In the process, we should recommend an API way to do it, if there is one, or quickly consider providing as an API. If we can do neither of those, then it will be made visible upon any reasonable request with a concrete use-case. Making a package visible in this case does not make it API, and the adopter must understand they will be broken in future releases (or even milestones) and these very internal classes will be changed as needed. There might be some legitimate deviations to this gracious flexibility, but it would require PMC review and approval. For example, there could be some cases that allowing clients access to some non-API could result in dangerous, data-loss behavior, or breaking-for-everyone-else behavior (in other words, not a reasonable request or use-case).
- At no time should this technique be seen as a way to "force" adopters to migrate to some API, or ever have even an appearance of denying any adopter access to functionality. While researchers or individual hackers could be expected to hack up their own access rules if for some reason they wanted to access internal packages, we need to make sure no one providing products is tempted to change our access rules and redistribute our bundles with modified access rules. That would have negative consequences for the whole ecosystem.
- For visible non-API packages, the correct use of x-friends and x-internal is still required.
- The visibility of a package must be finalized at least one full milestone before API freeze, and most should be complete two milestones before API freeze. This is to allow reasonable time for feedback and re-considerations if adopters find a reason to make something visible by the API freeze. After the API freeze, packages could be changed from hidden to visible, if reason is found.
To be clear, this change in policy is not an effort to make all internal classes not-visible. The policy is simply to say that it is no longer required to make everything visible. If done correctly, with good API design, no adopter would ever be effected in any way by this change in policy. While there is some risk in making this change, it is hopefully about the same level as saying that developers are free to use final classes, package visible classes, and private variables, when their code is correctly designed.
We acknowledge there is a good deal of community concern about this change in policy. Many good comments have been captured in bug 202711 and on the wtp-dev mailing list and on cross-project list. We very much appreciate everyone taking the time to give their thoughts. Our impression is that there is no completely obvious reason that forces one policy over another and that we can accomplish our WTP goals, while avoiding concrete problems that many seem concerned about. I've tried to summarize some of the arguments for and against various policies at Dialog on Visibility.
We, the PMC and project leads, will closely monitor the use of this policy and we will reevaluate if there are many cases of on-going concrete problems caused.