Push 23 August 1bb5b46bb326 MethodHandle equals bug

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Aug 25 02:02:08 PDT 2010


On 25/08/10 09:54, Rémi Forax wrote:
> Le 25/08/2010 05:07, Howard Lovatt a écrit :
>    
>> Hi,
>>
>> I think I might have found another bug:
>>
>>       final ActionListener al4 = Main#print( ActionEvent );
>>       b1.addActionListener( al4 );
>>       b1.doClick();
>>       b1.removeActionListener( al4 );
>>
>> Where print is:
>>
>>     private static void print( final ActionEvent notUsed ) {
>>       out.println( "Main.print method called" );
>>     }
>>
>> and b1 is a JButton. It gives:
>>
>> Main.print method called
>> Exception in thread "main" java.lang.ClassCastException: required
>> class java.awt.event.ActionEvent but encountered class $Proxy0
>> 	at sun.dyn.MethodHandleImpl.raiseException(MethodHandleImpl.java:1246)
>> 	at sun.dyn.FromGeneric$A2.invoke_I2(FromGeneric.java:531)
>> 	at java.dyn.MethodHandle.invokeVarargs(MethodHandle.java:328)
>> 	at com.sun.runtime.ProxyHelper$1.invoke(ProxyHelper.java:57)
>> 	at $Proxy0.equals(Unknown Source)
>> 	at javax.swing.event.EventListenerList.remove(EventListenerList.java:224)
>> 	at javax.swing.AbstractButton.removeActionListener(AbstractButton.java:1935)
>> 	at lambdas.Main.lambdas(Main.java:84)
>> 	at lambdas.Main.main(Main.java:20)
>>
>> Therefore the method reference is added OK, but can't be removed.
>> Seems to be something to do with the equals method implemented by the
>> MethodHandle.
>>
>> Sorry to keep finding bugs,
>>
>>     -- Howard.
>>
>>      
> It's a standard j.l.r.Proxy problem :)
>
> proxy1.equals(proxy2) is translated to
> proxy1.mh1.equals(proxy2) instead of proxy1.mh1.equals(proxy2.mh2).
>
> the usual solution is to not propagate a call to equals to
> the underlying proxee (here the method handle)
> and don't forget to also trap calls to hashCode().
>
> Rémi
>
>
>    
Yeah - I'm working on a fix - all Object.XXX calls should indeed 
dispatched to the underlying method handle instance (current impl 
erroneously call the handle invoke() method instead).

Maurizio


More information about the lambda-dev mailing list