Some Classes with a public void close() don't implement AutoCloseable
Eric Vergnaud
eric.vergnaud at wanadoo.fr
Mon Apr 20 01:13:49 UTC 2020
I don’t disagree with the analysis, but isn’t the problem precisely that IO objects can be instantiated (and thus opened) outside a TWR?
An option could be to disallow instantiation (of AutoOpenable) outside a TWR header, and disallow close() anywhere.
It’s probably too much of a breaking change to apply this to existing IO classes, but creating a new package (which would internally leverage the existing IO doesn’t sound like a big task.
> Le 20 avr. 2020 à 01:24, Remi Forax <forax at univ-mlv.fr> a écrit :
>
> TWR really means try-with-IO-resources.
>
> Java IO objects (InputStream/Channel etc) uses a 2 transitions model instead of a 3 transitions model, something i've always found smart.
> Instead of new -> open -> close, it's new/open -> close. The object creation and the opening of the resource are concomitant.
> Obviously you have exception (URLConnection) and all the buffered streams [0] but the idea is that the resource object is first allocated and in the constructor the resource is allocated so you have no issue with OutOfMemoryError.
>
> TWR is tailored to follow that model, that why it's not a good construct for locks (new -> lock -> unlock) or any objects that have a 3 transition model.
>
> If a some point we want to introduce a construct for the 3 transition model, instead of trying to patch TWR, it may better to consider it as its own construct and see it can be retrofit it as TWR in a second step.
>
> regards,
> Rémi
>
> [0] java.nio.file.Files alswo introduce in Java 7 provides methods carefully designed to create and open buffered streams in one call.
>
> ----- Mail original -----
>> De: "John Rose" <john.r.rose at oracle.com>
>> À: "Eric Vergnaud" <eric.vergnaud at wanadoo.fr>, "Florian Weimer" <fw at deneb.enyo.de>, "Brian Goetz"
>> <Brian.Goetz at oracle.com>
>> Cc: "discuss" <discuss at openjdk.java.net>
>> Envoyé: Samedi 18 Avril 2020 20:27:52
>> Objet: Re: Some Classes with a public void close() don't implement AutoCloseable
>
>> On Apr 18, 2020, at 8:54 AM, Eric Vergnaud <eric.vergnaud at wanadoo.fr> wrote:
>>>
>>> If TWR accepted both AutoOpenable and AutoCloseable, then there would be no
>>> break the current behavior, but it would become possible to implement the now
>>> desired behavior?
>>> (appreciate this would require some additional thinking for existing
>>> AutoCloseable classes)
>>
>> Yes, that’s the opening motion of a long and searching conversation. Getting it
>> wrong leads to Brian’s “epicyclical bags”, turning a simply-flawed design into
>> a complexly-flawed one. Getting it right is what Mark calls “selective
>> sedimentation”, that carefully matches good ideas from other languages to
>> Java’s peculiarities without breaking backward compatibility. It takes much
>> time and effort to seal these deals.
>>
>> FTR my precedents here are C++ RAII and Scheme’s dynamic-wind, which are only
>> starting points. I haven’t looked closely at Python or Mesa or Modula3, which
>> are probably relevant, since they are system-building languages with objects
>> and some CF abstraction. Common Lisp and Smalltalk make the same compromises
>> as today’s TWR in Java. (Sorry; never heard of Prompto, but I do know that with
>> care you can build compositional open/close resources out of objects.)
>>
>> One hard part is coaxing Java‘s object-oriented types to host yet another
>> control flow abstraction, even a small one; AutoCloseable is a very carefully
>> balanced OO design (look at its exception handling). It’s very hard to write
>> CF abstractions so they compose in the OO style. (Yes, it’s easy to propose
>> hooks as we are discussing but hard to make them hang together cleanly.) Just
>> pointing out a precedent, or a proposed “hook”, or a surprising mis-feature, as
>> we are doing here, is about 2% of the effort.
>>
>> Brian is right to mention for-each, which is an even trickier problem. There are
>> uncertain futures which may be relevant to TWR extensions: Loom’s
>> continuations are currently under the covers, but might need a way to interact
>> with re-entrant blocks (that’s part of dynamic-wind). We know that Java may
>> need new abstraction tools to model parts of Java’s built-in language, to unify
>> primitives with values—it is possible that these tools, once built, may provide
>> the best approach to some TWR 2.0 which is decisively better, rather than a
>> bolt-on. Or, maybe after running some corpus experiments and getting several
>> architect types on EGs to think for a few weeks about it, something like what
>> we are discussing here might turn out to be an economical move.
>>
>> The actual hook I’m suggesting here is not the interesting part of TWR’s
>> technical debt to me—such hooks were surely discussed originally and rejected
>> for reasons Brian suggested. The interesting part (to me) is the practical
>> results of the deliberate simplification of TWR, which I have ventured to call
>> (in hindsight *only*) a mis-feature, because (only in hindsight) we have
>> realized that it doesn’t sufficiently encourage exactly-correct placement of
>> the opening bracket that TWR will close, *in a minority of use cases*.
>> Normally we don’t design for a minority of use cases, but we might reconsider
>> if those use cases are not otherwise controllable by the user.
>>
>> What’s the minority use case here? Well, it’s the need (by some users) to
>> clearly and exactly separate argument checking and setup (including low-level
>> effects on JVM stack and heap!) from the actual commit-to-open (in some lock
>> abstractions), leading to a hard-to-solve “lost close” problem that was only a
>> vague theory when TWR was designed. Now we are clumsily patching around some
>> of these problems at the JVM level (JDK-8046936) and I’m beginning to think
>> there’s a more comprehensive and reliable solution that involves help from the
>> user, via an amendment to TWR.
>>
>> Anyway, this conversation may elucidate some technical debt or investment
>> opportunity concerning TWR but executing on it (even with a small “tweak”) will
>> require time and effort, far outside the scope of an email thread. Most of us
>> know this, but it bears repeating, because it’s easy to forget in the heat of
>> the creative moment.
>>
>> A good exposition of how small changes can be made to Java is this by Joe Darcy
>> for Project Coin:
>> https://wiki.openjdk.java.net/display/Coin/Main
>>
>> HTH!
>>
>> — John
More information about the discuss
mailing list