Please: try-with-resouces Lock support!

Reinier Zwitserloot reinier at zwitserloot.com
Fri Mar 11 19:58:58 PST 2011


The snippet implies this because it does something with 'r' when an
exception occurs, hence strongly suggesting that the author expected
"SomeException" to occur in the body of the try and not on the initializing
expression. (See quoted post below for context). The point I was trying to
make is: This is simply an alternative interpretation of the ARM block, and
one that is not *currently* compatible with how ARM is specified. Whether or
not its a use case that needs catering to is not something I commented on,
but I did attempt to point out that *IF* this use case is deemed important,
*AND* the doubly-nested try block is deemed too unwieldy to cater to it,
that there's no way out but to either (A) introduce a keyword, or (B) define
that the variable is initialized to 'null' if the initializing expression
fails.

The remainder of your post seems to be based on the confusion that I was
somehow advocating for the alternative use-case, so I assume no further
clarifications are required.

Removing the ability to catch/finally on an ARM try probably doesn't make it
any easier to work with; programmers will naturally assume that, as the
keyword 'try' is used, that finally and catch are allowed to be tacked on.
Removing the ability to do so also means the keyword should change from
'try' to something else ('do' is the most likely target if no new keywords
are allowed to be added as per coin's manifesto). Such a drastic change is
probably no longer feasible for java 7 at this point in time. I'm also not
sure try is truly as complicated as its being made out in practice. The
common use cases pretty much all work on the basis that the initializing
expression is just as likely to throw an exception as the usage of the
resource itself, and there's nothing useful to be gained by having access to
the variable in the catch block.

 --Reinier Zwitserloot



On Wed, Mar 9, 2011 at 10:17 PM, <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.
>
> 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