Lambda and multi-catch
David M. Lloyd
david.lloyd at redhat.com
Thu Mar 6 12:46:41 UTC 2014
On 03/06/2014 05:29 AM, 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 !' :(
> 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).
>
> 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).
I've noticed that the Oracle JDK 7 also uses the common supertype
instead of two catch clauses, which caused trouble for my seven2six
bytecode translator when a new exception common supertype was introduced
in the hierarchy in JDK 7 (but it could cause trouble in other, normal
cases of upgrade as well).
I figured this was some form of optimization. But doesn't it make more
sense to rely on the JVM to optimize this case? A paranoid fellow might
interpret it as a deliberate move to make binary compatibility even more
difficult than it is today.
Or is it a mistake that the JDK ever did this?
--
- DML
More information about the compiler-dev
mailing list