Multi-catch/final rethrow

joe.darcy at oracle.com joe.darcy at oracle.com
Mon May 3 17:25:00 PDT 2010


Greetings,

As alluded to as a possibility previously [1], I'm happy to announce 
that improved exception handling with multi-catch and final rethrow will 
be part of an upcoming JDK 7 build.  Improved exception handling is 
joining other Project Coin features implemented in the repository after 
successful experiences with a multi-catch implementation developed by 
Maurizio Cimadamore.

Maurizio's work also revealed and corrected a flaw in the originally 
proposed static analysis for the set of exception that can be rethrown [2]:

>  [a] final catch parameter is treated as throwing precisely those 
> exception types that
>     - the try block can throw,
>     - no previous catch clause handles, and
>     - is a subtype of one of the types in the declaration of the catch 
> parameter

Consider a final rethrow statement as below where the dynamic class of a 
thrown exception differs from the static type (due to a cast in this case):

class Neg04 {
  static class A extends Exception {}
  static class B extends Exception {}

  void test(boolean b1, boolean b2) throws B {
      try {
          if (b1) {
              throw new A();
          } else if (b2) {
              throw new B();
          } else {
              throw (Throwable)new Exception();
          }
      }
      catch (A e) {}
      catch (final Exception e) {
          throw e;
      }
      catch (Throwable t) {}
  }
}

The set of exceptions thrown by the try block is computed {A, B, 
Throwable}; therefore, the set of exceptions that can be rethrown is the 
set of exceptions from the try block:

* minus A, handled by a previous catch clause, giving {B, Throwable}
* minus Throwable since Throwable is not a subtype of one of the types 
declared for the catch parameter (just Exception in this case), leaving 
just {B}

However, if an Exception is thrown from the try it should be caught in 
the "catch(final Exception e)" clause even if the exception is cast to 
Throwable since catch clauses work based on the runtime class of the 
exceptions being thrown.

To address this, the third clause is changed to

> - is a subtype/supertype of one of the types in the declaration of the 
> catch  parameter

More formally, this clause covers computing a join over the set of 
thrown exceptions, eliminating subtypes.  In the example above 
{Throwable} is computed as the set of exceptions being throwable from 
the try block.  This is then intersected with the exceptions that can be 
caught by the try block, resulting in {Exception}, a properly sound result.

Very general exception types being thrown by a try block would reduce 
the utility of multi-catch since only imprecise information would be 
available.  Fortunately, from analyzing the JDK sources, throwing a 
statically imprecise exception seems rare, indicating multi-catch with 
the amended specification should still be very be helpful in practice.

Today the adventurous can apply a changest [3] to a copy of the JDK 7 
langtrools repository and build get a javac supporting this feature.  
Otherwise, the change will appear in promoted JDK 7 builds in due 
course. [4]

-Joe

[1] "Project Coin: Post-Devoxx Update, closures and exception handling," 
http://blogs.sun.com/darcy/entry/projec_coin_post_devoxx_closures

[2] "Improved Exception Handling for Java," 
http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000003.html

[3] http://hg.openjdk.java.net/jdk7/tl/langtools/rev/a6f2911a7c55

[4] http://download.java.net/jdk7/binaries/



More information about the coin-dev mailing list