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