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 <https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3> ). https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.2 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). https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6 I am pretty sure that this would not end well :) ] Simon
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev