Lambda and multi-catch

David Holmes david.holmes at oracle.com
Fri Mar 7 05:15:30 UTC 2014


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 compiler-dev mailing list