UPDATED: Rethrows Clause

Mark Mahieu markmahieu at googlemail.com
Mon Mar 30 17:04:13 PDT 2009


Forgot my JLS references in the first one...



HTML version + prototype available at:

	http://slm888.com




Rethrows Clause
v0.1.1


AUTHOR(S):

Mark Mahieu


OVERVIEW

FEATURE SUMMARY: Should be suitable as a summary in a language tutorial.

A new clause on method declarations which allows exception  
translations (wrapping and rethrowing as a different type) to be  
cleanly defined separately from the body of the method.  In many  
cases, checked exception type names do not then need to be repeated  
in a method's throws clause and in a throw statement in the method body.


MAJOR ADVANTAGE: What makes the proposal a favorable change?

The proposal adds direct support for a common idiom in daily use by  
Java programmers worldwide, allowing them to express their intentions  
with greater clarity and ease.  In comparison with some proposals,  
this is an attempt to make dealing with checked exceptions easier by  
increasing the expressiveness of exception handling code in general,  
rather than by attempting to deprecate checked exceptions in favour  
of unchecked exceptions.


MAJOR BENEFIT: Why is the platform better if the proposal is adopted?

There is a reduction in the amount of boilerplate Java programmers  
have to read and write for code dealing with checked exceptions.   
Declarations specifying both thrown and rethrown (wrapped) exceptions  
are kept together, aiding comprehension of the code.


MAJOR DISADVANTAGE: There is always a cost.

As with any syntax sugar which enables an alternative way of  
expressing an existing idiom, programmers may be tempted to use it  
even when the existing idiom would be more appropriate.


ALTERNATIVES: Can the benefits and advantages be had some way without  
a language change?

No.


EXAMPLES

SIMPLE EXAMPLE: Show the simplest possible program utilizing the new  
feature.


Before:

     void before() throws ConfigException {
         try {
             Class.forName("where.is.the.Code");
         }
         catch (ClassNotFoundException e) {
             throw new ConfigException(e);
         }
     }

After:

     void after()
         catch ClassNotFoundException throw ConfigException {

         Class.forName("here.is.the.Code");
     }


ADVANCED EXAMPLE: Show advanced usage(s) of the feature.

Before:

     void suspendAccount()
         throws AuthorizationException,
                PersistenceException {
         try {
             checkMyAuthoritah();
             db.update(/*...*/);
             log.recordInfo(/*...*/);
         }
         catch (InfernalDBException e) {
             throw new PersistenceException(e);
         }
         catch (InfernalLogException e) {
             throw new RuntimeException(e);
         }
     }

After:

     void suspendAccount()
         throws AuthorizationException
         catch InfernalDBException throw PersistenceException,
               InfernalLogException throw RuntimeException {

         checkMyAuthoritah();
         db.update(/*...*/);
         log.recordInfo(/*...*/);
     }


DETAILS

SPECIFICATION: Describe how the proposal affects the grammar, type  
system, and meaning of expressions and statements in the Java  
Programming Language as well as any other known impacts.

The syntactic grammar is modified to allow an optional rethrows  
clause immediately prior to a MethodBody:

         MethodDeclaratorRest:
                  FormalParameters {[]} [throws  
QualifiedIdentifierList] ( ( [catch ExceptionTranslationList]  
MethodBody ) | ; )

         ExceptionTranslationList:
                  QualifiedIdentifier throw QualifiedIdentifier { ,  
ExceptionTranslationList }



JLSv3 §8.4.6 : A rethrows clause lists one or more exception  
translations, each translation consisting of a caught type C and a  
translated type T for which all of the following must hold:
     * C <: java.lang.Exception
     * T < java.lang.Throwable
     * Neither C nor T is a type variable.
     * T has an accessible constructor suitable for rethrowing a  
value of type C (see below).
     * T is not the same type as C.

Any exceptions thrown by the method body which are a subtype of a  
caught exception type in the rethrows clause, are rethrown as the  
corresponding translated exception type.

For a given translated type T with corresponding caught type C, if T  
has an accessible constructor accepting a value of type C, then the  
translation is equivalent to the following:

     catch (C e) {
         throw new T(e);
     }

Otherwise it must have an accessible no argument constructor, and the  
translation is equivalent to:

     catch (C e) {
         throw new T().initCause(e);
     }


A rethrows clause does not restrict which types may appear in a  
throws clause for the same method.  In particular, for a given caught  
type C in the rethrows clause, it is permitted for some type C1 :> C  
to also be listed in the throws clause.


JLSv3 §8.2 : The set of exception types declared to be thrown by a  
method is the union of:
     * the types in the throws clause
     * the translated types in the rethrow clause
     * the types thrown by the translated types' selected constructors

JLSv3 §11.2.2 : For the purposes of exception analysis, the set of  
checked exception types which may be thrown by the method's body is  
the union of:
     * the types in the throws clause
     * the caught types in the rethrows clause

JLSv3 §11.2.3 : It is a compile-time error if a rethrows clause  
contains a translation from a checked exception type C but there  
exists no checked exception type E such that all of the following hold:
     * E <: C
     * The method body can throw E
     * No preceding translation in the rethrow clause catches E or a  
supertype of E
unless C is the class java.lang.Exception.

JLSv3 §13.4.21 : Changes to the rethrows clause of methods or  
constructors do not break compatibility with existing binaries; these  
clauses are checked only at compile time.



COMPILATION: How would the feature be compiled to class files? Show  
how the simple and advanced examples would be compiled. Compilation  
can be expressed as at least one of a desugaring to existing source  
constructs and a translation down to bytecode. If a new bytecode is  
used or the semantics of an existing bytecode are changed, describe  
those changes, including how they impact verification. Also discuss  
any new class file attributes that are introduced. Note that there  
are many downstream tools that consume class files and that they may  
to be updated to support the proposal!

A simple desugaring could consist of enclosing the method body's  
statements in a try statement, with catch clauses for each translated  
exception type.  For example, the following method:

     Method findMethod()
         catch ClassNotFoundException throw ConfigException,
               NoSuchMethodException throw ConfigException {

         Class<?> c = Class.forName("some.Thing");
         return c.getDeclaredMethod("execute", null);
     }

would be desugared to:

     Method findMethod()
         throws ConfigException {
         try {
             Class<?> c = Class.forName("some.Thing");
             return c.getDeclaredMethod("execute", null);
         }
         catch (ClassNotFoundException e) {
             throw new ConfigException(e);
         }
         catch (MethodNotFoundException e) {
             throw new ConfigException(e);
         }
     }

No changes to the classfile format are required.


TESTING: How can the feature be tested?

An initial set of jtreg tests is included in the prototype.


LIBRARY SUPPORT: Are any supporting libraries needed for the feature?

No


REFLECTIVE APIS: Do any of the various and sundry reflection APIs  
need to be updated? This list of reflective APIs includes but is not  
limited to core reflection (java.lang.Class and java.lang.reflect.*),  
javax.lang.model.*, the doclet API, and JPDA.

com.sun.source.tree.MethodTree would require updates to access the  
rethrows clause's caught and translated types.


OTHER CHANGES: Do any other parts of the platform need be updated  
too? Possibilities include but are not limited to JNI, serialization,  
and output of the javadoc tool.

No


MIGRATION: Sketch how a code base could be converted, manually or  
automatically, to use the new feature.

Catch clauses which simply wrap and rethrow an exception as another  
exception type not caught in an enclosing scope, can be trivially  
replaced with a rethrows clause, either manually or automatically.

It should be possible for tools to offer bidirectional conversions  
such that an exception translation may be moved back into the method  
body if it is subsequently decided that additional logic is required.


COMPATIBILITY

BREAKING CHANGES: Are any previously valid programs now invalid? If  
so, list one.

No


EXISTING PROGRAMS: How do source and class files of earlier platform  
versions interact with the feature? Can any new overloadings occur?  
Can any new overriding occur?

The semantics of existing class files and legal source files are  
unchanged by this feature.


REFERENCES

EXISTING BUGS: Please include a list of any existing Sun bug ids  
related to this proposal.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270
(similar, but emphasizes unchecked exceptions)


URL FOR PROTOTYPE (optional):

http://slm888.com/javac




More information about the coin-dev mailing list