Push 23 August 1bb5b46bb326 MethodHandle equals bug

Rémi Forax forax at univ-mlv.fr
Wed Aug 25 01:54:20 PDT 2010


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



More information about the lambda-dev mailing list