On Thu, May 4, 2017 at 5:19 PM, BJ Hargrave <hargr...@us.ibm.com> wrote:

> Again, see https://docs.oracle.com/javase/specs/jls/se7/html/jls-
> 13.html#jls-13.4.15.
> If an API is released and then you change the API such that the return
> type is different, e.g. List to Collection, that is a binary incompatible
> change. The user of the API may expect it to be a List and invoke List
> methods on it.

Changing the return type from a more specific type (e.g. List ) to a more
general type (e.g. Collection) is an intrinsically breaking change, for the
reasons you note.

Changing in the other direction from a more general type to a more specific
one is not intrinsically breaking, since we know the value returned by the
new method must be assignment compatible with the old code:

If the method returns a reference type, only an *areturn* instruction may
be used, and the type of the returned value must be assignment compatible
with the return descriptor of the method (JLS §5.2, §4.3.3


The reason that the change is  not binary compatible in the JVM due to the
way that linkage is specified. The parameter and return types that combine
with the class and method name to be invoked are mangled into a method
descriptor, which is as a utf8 constant, and matching for linkage is done
using that constant.

Converting a class file to invoke the method with the new return type
simply requires replacing the appropriate thing in the constant pool. This
 may require changes to up to three constants, depending on whether there
are other method references that share the old descriptor.
 Metadata could be associated with a bundle indicating that if a specific
 set of method refs / name and types / descriptors  are updated in the byte
code, the updated bundle can be consider to have only undergone a minor
change, rather than a major.

[ Alternatively, I believe it might technically be possible to have two
methods in a class file that differ only in return type.
 The JVMS states that "No two methods in one class file may have the same
name and descriptor", and the prolog code doesn't seem to parse the
descriptor in places that one would expect it to (e.g. checking for
non-override of final methods).


I am pretty sure that this would not end well :)  ]

OSGi Developer Mail List

Reply via email to