Lambda and multi-catch

Ivan Babanin babanin at gmail.com
Sat Mar 8 18:31:15 UTC 2014


> 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).

I got source from http://hg.openjdk.java.net/jdk8u/jdk8u

After a brief analysis, I found the problem in
LambdaToMethod.visitVarDef(...):438. 
Tree translator creates JCVariableDecl (line 444) and ignores vartype of
original tree, 
that's why Gen. genCatch(...) generate only single catch in exception table.

I think my code (surrounded by comments) will fix this bug:

result =
make.at(tree).VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tr
ee.sym), init);
// Copy vartype from original tree for variables with multiple types
if (tree.vartype.hasTag(TYPEUNION)) {
   ((JCVariableDecl) result).vartype = tree.vartype;
}
//

sy,
Ivan



More information about the lambda-dev mailing list