ARM and repeating exceptions

Joe Darcy joe.darcy at oracle.com
Wed May 23 08:03:21 PDT 2012


Hello Aleksey,

On 5/22/2012 10:41 PM, Aleksey Shipilev wrote:
> Hi Joe,
>
> On Wed, May 23, 2012 at 3:41 AM, Joseph Darcy<joe.darcy at oracle.com>  wrote:
>> The semantics of the try-with-resources statement are defined in the Java
>> Language Specification:

The desugarings for try with resources in JLS 14.20.3.1 and JLS 14.20.3.2:

try (VariableModifiers_opt R Identifier = Expression ...)
     Block

=>

{
     final VariableModifiers_minus_final R Identifier = Expression;
     Throwable #primaryExc = null;

     try ResourceSpecification_tail
         Block
     catch (Throwable
     ...
}

etc., define precisely what try-with-resources means.  This meaning does 
not support the usage pattern you have brought up.


> I have failed to see where in the spec you can find this:
>
>>   One exception should be at most the cause of XOR suppressed by another.
> The wording and spirit of Throwable.addSuppressed API argues it should
> be used when you have *another* exception and only one needs to be
> propagated. In the test case like mine you can *single* exception that
> needs to be propagated, so there is no reason to suppress any other
> exceptions.
>
> That said, imposing that additional requirement without even
> mentioning this in spec violates the "principle of least
> astonishment".
>

The the Project Coin/JSR 334 effort took pains to include javadoc for 
Throwable.addSuppressed to discuss the difference between caused by and 
suppressed:

"Note that when one exception causes another exception, the first 
exception is usually caught and then the second exception is thrown in 
response. In other words, there is a causal connection between the two 
exceptions. In contrast, there are situations where two independent 
exceptions can be thrown in sibling code blocks, in particular in the 
try block of a try-with-resources statement and the compiler-generated 
finally block which closes the resource. In these situations, only one 
of the thrown exceptions can be propagated. In the try-with-resources 
statement, when there are two such exceptions, the exception originating 
from the try block is propagated and the exception from the finally 
block is added to the list of exceptions suppressed by the exception 
from the try block. As an exception unwinds the stack, it can accumulate 
multiple suppressed exceptions.

An exception may have suppressed exceptions while also being caused by 
another exception. Whether or not an exception has a cause is 
semantically known at the time of its creation, unlike whether or not an 
exception will suppress other exceptions which is typically only 
determined after an exception is thrown."

The javadoc for addSuppressed also states:

"IllegalArgumentException - if exception is this throwable; a throwable 
cannot suppress itself."

The desugaring of try-with-resource in your code occurs "inside" the try 
block and does not include the catch IOException.  In other words, the 
implicit call to close is logically inside the try {...}catch.  
Therefore, your code as written tries to have an exception suppress 
itself, which is rejected by the library code as documented.

Cheers,

-Joe





More information about the compiler-dev mailing list