8019622: (sl) ServiceLoadet.next incorrect when creation and usages are in different contexts

Alan Bateman Alan.Bateman at oracle.com
Wed Jul 3 19:35:29 UTC 2013

On 03/07/2013 18:56, Remi Forax wrote:
> Interesting !
> it's related to the way the compiler desugar lambda vs method reference.
> I've not taken a look to the generated code but I think I know why the 
> behaviour is different.
> If the code uses a lambda:
>   PrivilegedAction<Boolean> action = () -> hasNextService();
> the compiler will create a private method lambda$n and will infer it's 
> parameter type and return type,
> here the infered return type is Boolean and not boolean, so the boxing 
> of the result of hasNextService()
> is done inside the method lambda$n.
> If the code uses a method reference:
> PrivilegedAction<Boolean> action = this::hasNextService;
> No method lambda$n is generated, the compiler uses the method 
> hasNextService, so the boxing
> need to be done in the generated proxy at runtime.

I've checked the generated code and this does seem to be the case (thanks!).

> So the way to fix this issue is to not use String.format in 
> boxingDescriptor
> (It's the only method in TypeConvertingMethodAdapter  that uses format)
> private static String boxingDescriptor(Wrapper w) {
>   return '(' + w.basicTypeChar() + ")L" + wrapperName(w) + ';'
> }
I assume you mean "(" to avoid another puzzle :-)

That should fix it but I worry that this might be a bit brittle and 
maybe there be other code paths that will trigger loading of providers 
when building call sites that result in the same thing. It might be 
safer for now to just use inner classes here.


More information about the core-libs-dev mailing list