Lambda and multi-catch

David Holmes david.holmes at oracle.com
Thu Mar 6 22:15:38 PST 2014


On 7/03/2014 3:53 PM, Sam Pullara wrote:
> It is throwing an NPE when he dereferences the null o — I thought the
> same thing the first time I looked at it.

Ughhh. That was unnecessarily obscure.

So the issue is that use of Exception is catching exceptions it should not.

Thanks Sam.

David

> Sam
>
>
>
> On Thu, Mar 6, 2014 at 9:15 PM, David Holmes <david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
>
>     On 6/03/2014 9:29 PM, Remi Forax wrote:
>      > A colleague of mine have find a hairy bug,
>      > here is a simple code to reproduce it.
>      >
>      > import java.io.IOException;
>      >
>      > public class FunWithMultiCatch {
>      >     public static void main(String[] args) {
>      >       Runnable r = () -> {
>      >         try {
>      >           Object o = null;
>      >           o.getClass();
>      >           throw new IOException();
>      >         } catch(IOException | IllegalArgumentException e) {
>      >           System.out.println("KO !");
>      >         } catch(RuntimeException e) {
>      >           System.out.println("OK !");
>      >         }
>      >       };
>      >       r.run();
>      >     }
>      > }
>      >
>      > It prints 'KO !' :(
>
>     What am I missing? We throw IOException and have a catch block for
>     IOException so I would expect it to print "KO !".
>
>     I'm more surprised that a non-lambda version prints "OK !"
>
>      > The problem can be reproduced for any multi-catch inside a lambda,
>      > the exception table is clearly wrong, the IOException and IAE are
>     merged
>      > to their common supertype (java.lang.Exception).
>
>     That would definitely seem wrong, but more of an issue with catching
>     RuntimeExceptions in the first block that should be handled by the
>     second catch block. eg change it to throw IllegalStateException()
>     instead:
>
>     if (false) throw new IOException();
>     throw new IllegalStateException();
>
>     -> "KO !"   !!!WT!
>
>     David
>     -----
>
>      > private static void lambda$main$0();
>      >       Code:
>      >          0: aconst_null
>      >          ...
>      >         14: athrow
>      >         15: astore_0
>      >         16: getstatic     #8                  // Field
>      > java/lang/System.out:Ljava/io/PrintStream;
>      >         19: ldc           #9                  // String OK !
>      >         21: invokevirtual #10                 // Method
>      > java/io/PrintStream.println:(Ljava/lang/String;)V
>      >         24: goto          36
>      >         27: astore_0
>      >         28: getstatic     #8                  // Field
>      > java/lang/System.out:Ljava/io/PrintStream;
>      >         31: ldc           #12                 // String KO !
>      >         33: invokevirtual #10                 // Method
>      > java/io/PrintStream.println:(Ljava/lang/String;)V
>      >         36: return
>      >       Exception table:
>      >          from    to  target type
>      >              0    15    15   Class
>      > java/lang/Exception                            <------------ Oops
>      >              0    15    27   Class java/lang/RuntimeException
>      >
>      > The current workaround is to not use a multi-catch in a lambda.
>      >
>      > It seems that some version of Eclipse had the same issue but it's
>     fixed
>      > with the one I use (from 21 feb).
>      >
>      > cheers,
>      > Rémi
>      >
>      >
>
>


More information about the lambda-dev mailing list