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