User Tools

Site Tools


evolving_java-based_apis

This is an old revision of the document!


Des Rivières, J. Evolving Java-based APIs. 2007

Abstract

This document is about how to evolve Java-based APIs while maintaining compatibility with existing client code.

Comments

Yann-Gaël Guéhéneuc, 2014/02/06

This document is very interesting because it tells all about Java-based API evolution in one document (okay, in three separate pages) without wasting space but going straight to the point. It starts by defining some basic concepts, such as Component, Component API, and Client and different levels of compatibility between an old and a new version of the Component API wrt. Clients:

  • Contract compatibility: API changes must not invalidate formerly legal Client binaries;
  • Source code compatibility: API changes must not prevent Client code to compile against the new release of the Component;
  • Binary code compatibility: pre-existing Client binaries must link and run with the new release of the Component without recompiling;
  • Data compatibility: Component new implementation must contain readers for current and all past versions of the data format.

The document emphasises that source code compatibility is not necessary, because it argues that most API changes can be caught by the compiler and corrected by the developers. It is correct if the documentation regarding the transition between old and new API is sufficiently explicit for developers to easily find how to change their code.

Then, the document put forward the assumptions that “every aspect of the API matters to some Client” and that, therefore, the API must be compatible in principle and in practice: in principle, “all pre-existing Clients must still be legal according to the contracts spelled out in the [new] Component API specification”; in practice, “[p]re-existing Client binaries must link and run with the new release of the Component without recompiling”.

Contract compatibility is the highest form of compatibility and the one that must be sought when evolving a Component. Contract compatibility depends on the role played by the Component and the Client and what kind of changes occurred between the two versions of the API. The roles are “caller” and “implementor”:

  • a Component can offer an API and its implementation, it is the implementor; the Client access the API, it is the caller;
  • a Component can offer a “callback” API, it is the caller; the Client must implement the API, it is the implementaor.

and the question is “For roles played by Clients, would the […] API change render invalid a hypothetical Client making legal usage of the existing API?” The document then provides a table (augmented here with the addition of API methods to assess the contract compatibility of a change:

Types of Changes Roles
Method preconditions Strengthen Breaks compatibility for callers Contract compatible for implementors
Weaken Contract compatible for callers Breaks compatibility for implementors

Method postconditions Strengthen Contract compatible for callers Breaks compatibility for implementors Weaken Breaks compatibility for callers Contract compatible for implementors Field invariants Strengthen Contract compatible for getters Breaks compatibility for setters Weaken Breaks compatibility for getters Contract compatible for setters

evolving_java-based_apis.1391671177.txt.gz · Last modified: 2019/10/06 20:37 (external edit)