Please: try-with-resouces Lock support!

Bruce Chapman brucechapman at paradise.net.nz
Fri Mar 11 01:17:51 PST 2011


On 10/03/2011 10:17 a.m., brucechapman at paradise.net.nz wrote:
> Quoting Reinier Zwitserloot<reinier at zwitserloot.com>:
>
>> This snippet:
>>
>> try (Resource r = getResource()) {
>>   .....
>> } catch (SomeException e) {
>>   ... do something with r....
>> }
>>
>>
>> implies that getResource() is not expected to fail. This is quite
>> different
>> from for example an inputstream:
> implies how?
>
> Neal's post which you quote suggested to me the perspective that in t-w-r, any
> catch or finally clause is really about the resource initialisation (and
> closing), and NOT really (or at least not so much) about exceptions thrown in
> the block. If you want to catch exceptions in the block, use the nested try
> idiom suggested by Stephen's email and confirmed by Neal.  This is not obvious.
>   But your statement 'implies that getResource() is not expected to fail.' is not
> consistent with this perspective because you have a catch in the t-w-r, which
> signifies that you are expecting getResource() to fail (assuming any expected
> failure of close() doesn't need explicit handling).
>
> If the perspective above is correct (I am not saying it is - I am suggesting it
> might be), or at least leads to correct code, then maybe we should give a hint
> of that in the JSR spec so we (and people who will write books about this stuff,
> and people that will explain it to others) send people off in the right
> direction to start with.
>
> Then again, I may well be deluded.

Hmm, 24hrs of silence, no-one has said I am not deluded, no one has said 
anything, I am raising the confidence level on the deluded option, and 
off for a weekend of canoeing (provided the "possible" tsunami doesn't 
ruin that) to reground myself.

Bruce

> Bruce
>
>> try (InputStream r = new FileInputStream(file)) { ... }
>>
>> where an exception on the constructor call is expected and the current
>> specified behaviour of ARM matches this expectation (notably: that it
>> includes the initializing expression as part of the 'try').
>>
>> There are a few solutions when the expectation is for the expression not
>> to
>> fail as in the getResource example:
>>
>> (1) Do *NOT* consider the expression as part of the 'try'. Short of
>> introducing some new keyword to specify which behaviour you want,
>> Stephen's
>> example of try (Resource r = ...) { try { ..... }} does exactly that,
>> and is
>> the only way to do this.
>>
>> (2) Allow both with the same try statement. However, as in practice any
>> expression can theoretically fail with any exception, the solution
>> would
>> have to be that 'r' is set to null if the initializing expression does
>> not
>> complete normally. The syntax sugar to make this work isn't trivial but
>> it
>> can be done.
>>
>> One could then write:
>>
>> try (Resource r = getResource()) {
>>   ....
>> } catch (Exception e) {
>>   icon = Icons.DEFAULT_ICON;
>>   logger.log("App icon resource " + r.getURL() + " is not available",
>> e);
>> }
>>
>> and if the exception that triggered the catch block to run occurred in
>> the
>> evaluation of "getResource()", the above code would produce an NPE on
>> the
>> log line. Better than a core dump, I guess. As with any null resource,
>> such
>> a resource will not be closed, and no exception is caused by the fact
>> that
>> 'r' is null when its time to clean it up. (which would be following the
>> execution of the catch block).
>>
>> Whether doing this is a good idea is something I leave to the readers,
>> but
>> it is another consistent alternative and does look slightly cleaner,
>> though
>> there's far more magic going on with this version.
>>
>>
>>   --Reinier Zwitserloot
>>
>>
>>
>> On Sat, Mar 5, 2011 at 9:18 PM, Neal Gafter<neal at gafter.com>  wrote:
>>
>>> In the try-with-resource language construct, exceptions thrown during
>> the
>>> construction of the resource are caught in the catch clauses.
>> Therefore,
>>> making the resource in scope be within the catch clause would be
>> providing
>>> access to a variable that is not definitely assigned. Since a
>> variable
>>> that
>>> is final (by the try-with-resources specification), not definitely
>> assigned
>>> (because the exception might have occurred during the resource
>> expression),
>>> and not definitely unassigned (because the exception might have
>> occurred
>>> during the try block), it cannot be used in any way. There is
>> therefore no
>>> point in making the variable be in scope within the catch clause.
>>>
>>> The correct thing to do is Stephen' suggestion:
>>>
>>> On Sat, Mar 5, 2011 at 11:08 AM, Stephen Colebourne
>> <scolebourne at joda.org
>>>> wrote:
>>>> But there is a "hack" solution:
>>>>
>>>> try(Resource r = getResource()) {try {
>>>> doSomething(r);
>>>> } catch (ResourceException e) {
>>>> System.out.println(e + " from " + r); // r undefined here
>>>> }}
>>>>
>>>> Not ideal.
>>>>
>>> This is the correct solution, and it is both ideal and not a hack. I'm
>> not
>>> sure I agree with your spacing and placement of curly braces, but that
>> is a
>>> style issue. The semantics of this code are different (than a catch on
>> the
>>> try-with-resources statement) because the catch clause here only
>> catches
>>> exceptions thrown from within the inner try block. If you want to use
>> the
>>> resource variable, that is exactly what you need.
>>>
>>> At worst, this exchange demonstrates that the try-with-resources
>>> specification is piling too much complexity on the already overly
>> complex
>>> try statement.
>>>
>>> Cheers,
>>> Neal
>>>
>>>
>>
>
>




More information about the coin-dev mailing list