Proposal: Improved Exception Handling for Java (original) (raw)
Joseph D. Darcy Joe.Darcy at Sun.COM
Mon Mar 2 22:29:29 PST 2009
- Previous message: Proposal: Import Aliases for Classes and Static Methods
- Next message: Proposal: Improved Exception Handling for Java
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hello.
Comments in line...
Neal Gafter wrote:
[Resending in plain text]
Improved Exception Handling for Java AUTHOR(S): Neal M Gafter OVERVIEW FEATURE SUMMARY: Catching multiple exception types: A single catch clause can now catch more than one exception types, enabling a series of otherwise identical catch clauses to be written as a single catch clause. Improved checking for rethrown exceptions: Previously, rethrowing an exception was treated as throwing the type of the catch parameter. Now, when a catch parameter is declared final, rethrowing the exception is known statically to throw only those checked exception types that were thrown in the try block, are a subtype of the catch parameter type, and not caught in preceding catch clauses. MAJOR ADVANTAGE: Catching multiple exception types: Simplifies a commonly appearing pattern of redundant code. Improved checking for rethrown exceptions: This improvement makes it possible to add a try-catch statement around a block of code to intercept, process, and rethrow an exception without affecting the statically determined set of exceptions thrown from the code. MAJOR BENEFIT: Greatly simplifies writing and maintaining code where intercepting or processing exceptions is common. MAJOR DISADVANTAGE: One-time implementation cost for adding the features to the compiler. Longer language specification in describing the behavior.
What sort of poor programming practices could this feature encourage or enable?
ALTERNATIVES:
These behaviors are approximated currently by writing a series of identical catch clauses. During maintenance, the set of catch clauses must be modified so that it continues to match the set of exceptions statically thrown in the try block. With the proposed changes, the catch block can be written to catch a supertype of the set of exceptions to be intercepted, resulting in fewer catch clauses and fewer changes required when the try block evolves.
Another poor alternative used too often in practice is to catch a too general type, like Throwable, to avoid repeating more specific catch clauses.
EXAMPLES
SIMPLE EXAMPLE: try { doWork(file); } catch (final IOException|SQLException ex) { logger.log(ex); throw ex; } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. DETAILS SPECIFICATION: The grammar of Java is extended to allow a series of exception types, separated by the "OR" operator symbol, to be used in a catch clause: CatchClause: catch ( CatchFormalParameter ) Block CatchFormalParameter: VariableModifiers CatchType VariableDeclaratorId CatchType: DisjunctionType DisjunctionType: Type Type | DisjunctionType The type system is affected as follows: For the purpose of type checking, a catch parameter declared with a disjunction has type lub(t1, t2, ...) [JLS3 15.12.2.5].
In terms of finding the members of the type, it is good existing concepts in the JLS can be used.
What happens if someone writes
catch(final IOException | SomeSubclassOfIOException e) {...}
In other words, is it legal to have subclasses of a caught exception listed too?
For the purpose of exception checking [JLS3 11.2], a throw statement [JLS3 11.2.2] that rethrows 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 subtye of one of the types in the declaration of the catch parameter To avoid the need to add support for general disjunctive types, but leaving open the possibility of a future extension along these lines, a catch parameter whose type has more than one disjunct is required to be declared final.
I think that is a fine compromise that keep the current feature smaller while allowing room for a broader feature later.
Some worked examples of the sets of thrown exceptions types under various tricky code samples would help clarify the data flow algorithm for me.
COMPILATION:
A catch clause is currently compiled (before this change) to an entry in an exception table that specifies the type of the exception and the address of the code for the catch body. To generate code for this new construct, the compiler would generate an entry in the exception table for each type in the exception parameter's list of types.
Interesting; so there would be no code duplication even in the class files.
TESTING:
The feature can be tested by compiling and running programs that exercise the feature. LIBRARY SUPPORT: No. REFLECTIVE APIS: No reflective API changes are required. OTHER CHANGES: It would be desirable, at the same time that this change is made, to update the non-public Tree API that can be used with APT to express the syntax extension.
The Tree API (http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html) has a bit different situation than other APIs in the JDK. The tree API is not a JCP API, but we at Sun choose to ship it and document it as part of Sun's JDK. So the API is public in that sense, but it has a different support, stability, and compatibility contract than JCP APIs.
MIGRATION:
None required. However, it would be easy to detect a series of otherwise identical catch clauses for different types and collapse them to a single catch clause. COMPATIBILITY BREAKING CHANGES: Joe Darcy observes that the following program compiles before this change, but not after: try { throw new DaughterOfFoo(); } catch (final Foo exception) { try { throw exception; // used to throw Foo, now throws DaughterOfFoo } catch (SonOfFoo anotherException) { // Reachable? } } However This breakage is compile-time-only; already-compiled programs continue to behave as before This kind of breakage is very unlikely to occur in practice, and The broken code was likely wrong before, as it attempts to catch exceptions that simply cannot occur.
I am a bit concerned by the existence of such a program, as uncommon or ill-posed as it might be.
It is preferable to have a pure extension that doesn't invalidate any existing programs.
The platform promises JLS chapter 13 binary compatibility from release to release; that binary compatibility is defined to be the continued ability to link, nothing more. Source compatibility is not promised from release to release, and source compatibility is not defined in the JLS (I take a stab at drawing out source compatibility thread levels in http://blogs.sun.com/darcy/entry/kinds_of_compatibility). However, source compatibility should be maintained if possible.
How could the increased exception precision be maintained will still allow programs such as the one above to compile?
Thanks for sending this in,
-Joe
EXISTING PROGRAMS:
Except as above, none. REFERENCES EXISTING BUGS: No existing bugs that I am aware of. URL FOR PROTOTYPE (optional): An implementation of disjunctive catch parameters, but without special handling for final catch parameters: http://www.javac.info/ See also Catching Multiple Exception Types: http://www.javac.info/Multicatch.html Improved Checking for Rethrown Exceptions: http://www.javac.info/Rethrown.html
- Previous message: Proposal: Import Aliases for Classes and Static Methods
- Next message: Proposal: Improved Exception Handling for Java
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]