Lambda and multi-catch
 Ivan Babanin 
 babanin at gmail.com
 
 Fri Mar 7 23:50:38 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:
 LambdaTranslationContext lambdaContext =
(LambdaTranslationContext)context;
 if (context != null &&
lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
 JCExpression init = translate(tree.init);
 int prevPos = make.pos;
 try {
 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 ((result != null) && tree.vartype.hasTag(TYPEUNION)) {
 ((JCVariableDecl) result).vartype = tree.vartype;
 }
	//
 } finally {
 make.at(prevPos);
 }
sy,
Ivan
 
 
More information about the lambda-dev
mailing list