Java Reference
In-Depth Information
precise version of 1.0.0 on a package import, you would need to write ver-
sion="[1.0.0, 1.0.0]" . Specifying version="1.0.0" means any version
greater than 1.0.0.
But this import is pretty vague. The importer risks being broken by changes to the
food.experimental that aren't backward compatible. To avoid this, the importer
should explicitly specify a minimum and maximum range as follows:
Import-Package: food.experimental;version="[0.0.0,1.0.0)"
But what's a sensible range? The rules of semantic versioning don't apply to versions
below 1.0.0. Some projects (including Apache Aries) treat all minor increments below
versions 1.0.0 as potentially breaking changes. One sensible upper range is
"[0.0.0,0.1.0)" . On the other hand, when you release a new version of the
food.experimental package, you may decide to reform your nonversioning ways, and
start on a clean slate with a sensible version of 1.0.0 . Neither an import of
"[0.0.0,1.0.0)" nor "[0.0.0,0.1.0)" would be satisfied by a food.experimental
package exported with version 1.0.0, even if nothing significant had changed. The net
effect of this ambiguity is uncertainty for importers of the package. They won't know
whether a change from 0.0.0 to 1.0.0 is a breaking change or a trivial change to move
to a versioned package. The easiest way to avoid all the confusion is to start off as you
mean to go on and give packages meaningful versions from the first release.
A.2.5
Consumers and providers, not clients and implementors
One of the most confusing things about semantic versioning is that it can't be boiled
down to, “I implement interface X, therefore I need a version range of [1,1.1).” This
is why we talk about API providers and consumers rather than any less generic terms.
A provider of an API isn't only the bundle that exports the package, but also any
bundle that provides a backing implementation for use by a consumer. A good exam-
ple here would be the Servlet API and a Web Container implementation (for example,
Jetty). The Servlet API bundle is clearly a provider, but less obviously, so is Jetty. This is
because consumers of the Servlet API (web applications, to the developer) expect the
presence of a Web Container as well as the API classes.
It doesn't normally take much of an effort for people to understand that providers
may not export the API they use, they can still fall back on the mental model that if
they implement an interface then that makes them a provider. Unfortunately, this
isn't correct! Once again the Servlet API provides a good example. Clearly a web appli-
cation is a consumer of the Servlet API , but web applications extensively implement
abstract classes and interfaces from the Servlet API . Try writing a functional servlet
without extending Servlet or HttpServlet . There are plenty more examples in the
Servlet API , but also in other API s.
To truly understand semantic versioning, you need to have a clear division
between API interfaces that are implemented or extended by a provider (for example
HttpServletRequest ), and ones that are implemented or extended by the consumer
(for example HttpServlet ). If you add a method to an interface implemented by a
Search WWH ::




Custom Search