Artem Bilan opened SPR-12525 and commented

See the external linked discussion. The original issue is here: http://stackoverflow.com/questions/23863716/java-how-to-resolve-generic-type-of-lambda-parameter and its related SO question. I can confirm that using that typetools in the Spring Integration Java DSL I can avoid an extra type parameter. From this:

.handle(Integer.class, (p, h) -> p * 2)

to this:

.<Integer>handle((p, h) -> p * 2)

This fix allow us to fix other Lambda issues, e.g. #15303


Reference URL: https://github.com/jhalterman/typetools/issues/4

Issue Links: - #18273 ResolvableType should support resolving lambda types ("duplicates") - #15303 Inferring an ApplicationListener's event type from a lambda or method reference - #16427 @Aspect aspect not correctly applied to Java 8 lambda-defined @Beans - #18681 Wrong detection of event type on ApplicationListener<> when using lambdas (ClassCast Exception)

0 votes, 8 watchers

Comment From: spring-projects-issues

Juergen Hoeller commented

I've played around with the suggested code but unfortunately it seems to be very fragile and doesn't even seem to work for some lambda variants that I've tried. That aside, it relies on access to private JVM APIs that are not accessible on JDK 9 anymore. And I'm not keen on custom ASM digging in the constant pool either, which would still rely on the structures of entries there,

I'm afraid we can't provide this until standard JVM facilities are being provided for that purpose :-(

Juergen

Comment From: spring-projects-issues

Artem Bilan commented

No problem, Juergen!

Thank you very much for the investigation and explanation.

Since with API from our Frameworks we always can require an additional type parameter, we will live with the current JVM state until better times.

Comment From: spring-projects-issues

Jonathan Halterman commented

@Jurgen I just noticed your comments - a bit late :)

I agree that the ConstantPool technique for resolving lambda generics is not ideal, but when ConstantPool is present is should be fairly well and covers most lambda use cases (newer versions of TypeTools have improved on this though there is at least one corner case that is not covered). Do you recall which variants you tried that might not have worked?

I'm also seeing ConstantPool still alive and well in OpenJDK 9 builds, for what it's worth.

That all said, due to the target runtime limitations, this capability isn't something that everybody can benefit from and comes with the associated caveats.

Comment From: spring-projects-issues

Sam Brannen commented

FYI: the SerializedLambda approach may prove useful and more reliable than the ConstantPool approach; however, as Brian Goetz points out, "Serialized lambdas have significantly higher performance costs compared to nonserializable lambdas, and are less secure...".

Comment From: spring-projects-issues

Oliver Drotbohm commented

Looks like is basically a duplicate of #18273. I just had someone running into this problem again (declared a functional bean as lambda (a Spring HATEOAS ResourceProcessor and wondered why the generics aren't discovered properly).

Comment From: 8-bitLincoln

Looks like https://github.com/jhalterman/typetools has resolved this problem

Comment From: sbrannen

Looks like jhalterman/typetools has resolved this problem

Well, that my be true but unfortunately only for Java 8 and 9.

Lambda type argument resolution is currently supported for: * Oracle JDK 8, 9 * Open JDK 8, 9

Source: https://github.com/jhalterman/typetools#on-lambda-support

So, that's not a valid option.

Comment From: sdeleuze

I don't think Spring can build a feature that can cover all the lambdas use cases and JDK versions in a non brittle way, so I decline this feature request.