RFR: 8282080: Lambda deserialization fails for Object method references on interfaces [v2]

Liam Miller-Cushon cushon at openjdk.java.net
Sat Apr 30 19:39:33 UTC 2022

On Thu, 28 Apr 2022 18:36:48 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

>> Per JLS, every interface with no superinterfaces implicitly has all public methods `java.lang.Object` has (unless the interface declares them explicitly). So, having:
>> interface I {}
>> the interface has methods like `hashCode()`. But, before https://bugs.openjdk.java.net/browse/JDK-8272564, javac was referring to them as if they were a `java.lang.Object` methods, not the interface methods. E.g. saying `I i = null; i.hashCode()` lead to a reference to `java.lang.Object.hashCode()` not `I.hashCode()`. That was changed in JDK-8272564, and now the reference is to `I.hashCode()`.
>> There is one issue, though: when the reference is for a serializable (and serialized) method handle, the runtime method is still `java.lang.Object::hashCode`, but the deserialization code generated by javac expects `I::hashCode`, and hence the serialized method handle fails to deserialize.
>> The proposal here is to fix just this case, by changing the deserialization code to expect the method from `java.lang.Object`, which should revert the deserialization behavior back to JDK 17 behavior.
> Jan Lahoda has updated the pull request incrementally with one additional commit since the last revision:
>   Avoiding a use of a new flag to determine Object methods copied to interfaces.

Re: the impact of JDK-8272564, for what it's worth, it ended up being a noticeable breaking change for us:

* Some static analysis that was looking for interfaces noticed the 'sharper' static type information on these calls. This is an improvement, but still a breaking one.
* A non-OpenJDK runtime's verifier didn't handle the new calls (which is their bug, but confirms this is a slightly surprising edge case), and we ended up doing some bytecode munging to rewrite back to invokevirtuals for code affected by that.

At this point we've absorbed the breaking change and I personally don't have any concerns with the new behaviour, I'm just sharing that in case you're still weighing the risk of whack-a-mole from keeping JDK-8272564.


PR: https://git.openjdk.java.net/jdk/pull/8054

More information about the compiler-dev mailing list