Friday, September 30, 2011

The Needs of the Many Outweigh the Needs of the Few

There is a discussion on the Aries dev mail list about a tool for checking semantic versioning. One of the issues misunderstood in the discussion is about the asymmetry in the treatment of versions for the roles of API consumer and API provider discussed in the whitepaper.

An API package p can contains several types. Some types must be implemented by the API provider and some are intended to be implemented by the API consumer. p.S may be a service provided by the API provider and used by the API consumer. p.L may be a listener implemented by the API consumer and user by the API provider. A syntactic analysis tool for versioning needs to understand the orientation of a type to decide whether a change to the type constitutes a major version change for the package or a minor version change.

The whitepaper does not discuss how the orientation of the type should be marked. It is beyond the scope of the whitepaper. OSGi now uses the @noimplement javadoc tag (from Eclipse) to indicate the type is not to be implemented by the API consumer (e.g. p.S). Types not marked @noimplement may be implemented by the API consumers (e.g. p.L). Adding a new method to p.S represents a minor version increment to package p as API consumers are not broken (while API providers are broken; but they have tighter version constraints, e.g. [1.0,1.1)). Adding a new method to p.L represents a major version increment to package p as API consumers are broken. Furthermore adding a new type to package p will not break API consumers. They are free to ignore it. But API providers must change to support the new type.

These are examples of the asymmetry between API providers and API consumers: an API provider must provide all of the API while an API consumer is free to use any subset of the API.

So in order for any syntactic analysis tool to properly work, the orientation of the types in the package must be properly marked so the tool can decide whether a change warrants incrementing the major or minor version. What is missing is an agreement on how to mark the types. I think this is something bnd and bndtools should provide. Perhaps a set of standard annotations.

For any API, we see there is an asymmetry in the relationships is has with API providers and API consumers. In general, there will (hopefully) be many more consumers than providers. So the semantic versioning scheme is oriented towards the many: the API consumers.

"... the needs of the many outweigh the needs of the few." - Spock.

PS. It has also been suggested that segregating consumer oriented types from provider oriented types by placing them in different packages is useful. But this does not remove the need for syntactic analysis tools to understand the orientation of each type (or each package) to provide proper advice about necessary versioning changes. And now you have 2 packages which each provider and consumer must import...