JDK-8174983 : LambdaMetafactory: standardize supported type conversions
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 9
  • Priority: P3
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2017-02-14
  • Updated: 2021-09-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Blocks :  
Blocks :  
Relates :  
Relates :  
Description
The conversions allowed by LambdaMetafactory on parameter and return types are ad hoc and inconsistent with the specification.

Propose standardizing on the conversions supported by MethodHandle.asType, which are similar but a little more flexible.

Specifically:

factoryType.parameterType(i) --> implementation.type().parameterType(i)
Currently: same type (but receiver can be a subtype)
Change: allow any 'asType' conversion, including boxing & unboxing

dynamicMethodType.parameterType(i) --> implementation.type().parameterType(j)
Currently: ref subtype, prim widening, or box/unbox followed by these (but receiver can't be boxed)
Change: allow conversion between arbitrary refs; allow narrowing from a supertype before unbox; allow receiver to be boxed

interfaceMethodType.parameterType(i) --> dynamicMethodType.parameterType(i)
Currently: ref supertype, prim same
Change: allow any 'asType' conversion, including boxing & unboxing

implementation.type().returnType() --> dynamicMethodType.returnType()
Currently: any type targeting void, arbitrary refs, prim widening, box+widening, unbox+widening*
Change: allow void to target a non-void type; allow narrowing from a supertype before unbox

dynamicMethodType.returnType() --> interfaceMethodType.returnType()
Currently: void->void, ref subtype, prim widening, box+widening, unbox+widening
Change: allow either to be void; allow conversion between arbitrary refs; allow narrowing from a supertype before unbox

(*Current implementation allows any reference-typed implementation return to be compatible with any expected primitive type, as long as the reference type is not a box type (if it is a box type, unbox+widening applies). This is probably a bug.)
Comments
Elastic Search and Apache Lucene also interested on this bug. Comment from Uwe Schindler(Apache Lucene): In addition, I had some discussions with Rémi Forax on the Jaxcon 2017 this week and we discussed about the Elasticsearch "Painless" scripting engine. This one was using LambdaMetaFactory to compile lambdas in the scripting language, but with one of the recent java 9 updates, the whole think broke (mostly because of the "def" datatyle - aka Object in java. LambdaMetaFactory refuses to do some types of boxing/unboxing and type conversions, although the Javadoc/Spec tells that they are supported. It is only that Java code does not use such type of conversions, but the spec is incompatible to its documentation). We found the following issue: https://bugs.openjdk.java.net/browse/JDK-8174983 This looks like the issue. Because of this and the really not exactly specified type conversions, we decided to drop support for LambdaMetaFactory and implemented our own poor-man's LambdaBootstrap using a second invokedynamic to delegate to MethodHandles.asType() for the type conversions. IMHO, LambdaMetafactory should do the same! You can see more details in following links: - Elastic Search original issue: https://github.com/elastic/elasticsearch/issues/23473 - First fix: https://github.com/elastic/elasticsearch/pull/24070 - Second fix to correctly support Class::new method references: https://github.com/elastic/elasticsearch/pull/24406 - Implementation of Rémi's suggestions: https://github.com/elastic/elasticsearch/pull/24618 - Elastic Search LambdaBootstrap impl: https://goo.gl/4bBuo0
12-05-2017