D Merge Command Operative Principles

This appendix describes the command operative principles used by the Signature Test tool.

D.1 Merge Command Operative Principles

The Merge command operates according to the following principles, where A and B are input APIs that are combined into the resulting API C:

  • The Merge operation is commutative, so with API A and B, A + B = B + A.

  • It recognizes either binary or source compatibility when merging APIs.

  • For any application X that is compatible with either API A or B, when A and B are merged then X must be compatible with the resulting API C.

  • The resulting API C cannot contain a class that is not found in either of the A or B input APIs. This means that any class in C has to have corresponding classes in either A or B or both A and B.

  • API C must not contain a class member that is not found in its corresponding classes in A and B. This applies only to declared class members and not inherited members.

  • If some class in A or B, or both, has a member that overrides a member from a superclass, then the corresponding class in C must also have this overriding member.

  • Each API element in C has a set of attributes derived from the attributes of its corresponding elements in A and B, and this is the smallest possible set of attributes that does not break compatibility. So if attr is an attribute of an element from API C, then attr must be defined for the corresponding element from A or B, and attr cannot be omitted without breaking compatibility between A and C or between B and C.

  • No unnecessary APIs or relationships between classes or interfaces can be introduced.

The basic algorithmic rules for combining two input APIs A and B into a signature file that represents the resulting API C are as follows:

  • If one of the input APIs A or B contains an element that the other does not, then this element goes into the resulting signature file of API C without modification except for the following case: If the element in question is the first declared class member in the inheritance chain of input API A or B, and the other input API inherits the same element, then this element represented the resulting API C.

  • If both of the input APIs contain two identical elements, only one of them is represented in the resulting API.

  • If both of the input APIs contain a corresponding element, but with a different set of attributes, then either of the following occurs:

    • A conflict wherein the resulting API cannot exist.

    • A compromise wherein the new element with a composite set of attributes is created and it is represented in the resulting API-set.

D.1.1 Element Handling by Merge

General rules for handling elements of all kinds during the Merge process are as follows.

  • When there are two different access modifiers select the more visible one.

    For example, if A is a public int foo, and B is protected int foo, then the merge into C results into public int foo.

  • If the elements differ in the final modifier, do not include it. If a class is final, then all of its methods are implicitly final according to Section 8.4.3.3 of The Java Language Specification, 2nd Edition.

  • If corresponding elements differ in the static modifier, then declare a conflict.

Element-specific rules are as follows:

  • If corresponding classes differ in the abstract modifier, then declare a conflict.

  • Apply the following rules for classes or interfaces and nested classes or interfaces, where for the purpose of this description, c1 and c2 are corresponding classes from the input APIs:

    If a superclass of c1 is a subclass of a superclass of c2, use the superclass of c1 as the superclass for the new element. Otherwise, if a superclass of c2 is a subclass of a superclass of c1, use the superclass of c2 as the superclass for the new element. If neither of the previous two conditions are possible, then declare a conflict.

  • For classes or interfaces and nested classes or interfaces, create a combined set of superinterfaces of the corresponding classes and dismiss duplicates. Use the combined set for the new element.

  • For methods and constructors, construct a throws list as follows:

    • In binary compatibility mode, an empty throws list results independently of the source lists.

    • In source compatibility mode, both throws lists are normalized as described in Table 4-3 before they are compared. If the normalized lists are equal, one is used as the result, otherwise, a conflict is declared.

  • Methods that differ in the abstract modifier are not included.

  • If a method result type is not identical a conflict is declared.

  • If a field value type is not identical a conflict is declared.

  • If a field element differs in the volatile modifier, it is included.

  • Process constant field values as follows:

    • If one of the fields has a constant value and other does not, include the constant value in the result field.

    • If both fields have a constant value then declare a conflict if the values are different, otherwise include the value in the result field.