Quantcast
Channel: User Tagir Valeev - Stack Overflow
Viewing all articles
Browse latest Browse all 42

Answer by Tagir Valeev for Code coverage finally block

$
0
0

In the Java bytecode (at least since Java 1.6) there's no special construct for the finally block, so it is actually duplicated many times. For example, consider the following method:

public static void main(String[] args) {    try {        System.out.println("In try");        if(args.length > 0)            return;        System.out.println("No args");    }    catch(RuntimeException ex) {        System.out.println("In catch");    }    finally {        System.out.println("In finally");    }}

This code is effectively compiled to something like this:

public static void main(String[] args) {    try {        System.out.println("In try");        if(args.length > 0) {            System.out.println("In finally");            return;        }        System.out.println("No args");    }    catch(RuntimeException ex) {        System.out.println("In catch");        System.out.println("In finally");    }    catch(<any exception> t) {        System.out.println("In finally");        throw t;    }    System.out.println("In finally");}

This is not a fully equivalent code, because if new exception occurs during the System.out.println("In finally"); (before the return), then it will not be caught. However it shows the rough idea that the finally block is duplicated here four times. It can be duplicated much more times if you have several ways to exit your try block and especially if you have nested try-finally blocks. Also note the <any exception> special catch added. It will appear in the bytecode even if you explicitly write catch(Throwable t).

As code coverage tools like Emma or JaCoCo work on byte-code level, they are unaware that these four "In finally" printlns are actually the same statement in the source code. It's possible to perform a bytecode analysis and quite robustly determine which parts of bytecode correspond to the single source finally block (I actually wrote such analyzer once), but it's not very easy problem and has some non-trivial caveats. You also should take into account that different compilers (for example, javac and ecj) produce somewhat different layout of finally blocks. So seems that this work was not done in popular coverage tools and they just consider different finally block copies as different code.

In your particular case seems that @bobbel is right: you did not test the uncaught exception case (that <any exception> catch).


Viewing all articles
Browse latest Browse all 42

Latest Images

Trending Articles





Latest Images