RFR: 8017513: Support for closeable streams

Zhong Yu zhong.j.yu at gmail.com
Fri Jul 12 15:53:50 UTC 2013


On Fri, Jul 12, 2013 at 4:30 AM, Peter Levart <peter.levart at gmail.com> wrote:
> On 07/12/2013 01:14 AM, Zhong Yu wrote:
>
> On Thu, Jul 11, 2013 at 4:08 PM, Peter Levart <peter.levart at gmail.com>
> wrote:
>
> Hi Paul,
>
> I think the MayHoldCloseableResource extends AutoClosable is correct and
> AutoClosable extends MayHoldCloseableResource would be wrong.
>
> And exactly because of "Liskov":
>
> MayHoldCloseableResource contract says: "If you know it holds a resource,
> call close(), otherwise you need not call close(), but it's not wrong to
> call it anyway - you know whether it holds resource by looking at
> @HoldsResource annotation"
>
> AutoClosable contract says: "It holds a resource, you should call close()"
>
>
> Now imagine code that was written for the AutoClosable contract. Would it
> work if you pass it an instance of MayHoldCloseableResource? Allways.
>
> Now imagine generic code that was written for MayHoldCloseableResource
> contract and which uses the lookup of @HoldsResource at runtime to decide
>
> How do you lookup an annotation on an _instance_ at runtime?
>
>
> Hi Zhong (and Roger),
>
> Well, if @HoldsResource had RUNTIME retention, then by using:
>
> instance.getClass(), ... clazz.getSuperclass(), getInterfaces(), ... etc.
>
>
> And why
> do we even care? Just call close() regardless.
>
>
> I was just trying to illustrate a hypothetical code that works with
> MayHoldCloseableResource contract and breaks if AutoCloseable is passed to
> it. In case AutoCloseable was a subtype of MayHoldCloseableResource,
> considering Liskov substitution principle, it should work: "if S is a
> subtype of T, then objects of type T may be replaced with objects of type S
> (i.e., objects of type S may be substituted for objects of type T) without
> altering any of the desirable properties of that program (correctness, task
> performed, etc.)". In reality the decision about calling or not calling the
> close() is hard-coded by the programmer, guided by static analysis tools,
> IDEs and so on, but that doesn't change the reasoning.
>
>
>
> And we can revert the parent/child relation, because the "otherwise
> specified" clause is a panacea.
>
> Could you elaborate that?

A supertype can be very vague on its contract, making it possible that
subtypes of vast different behaviors can all be compatible with the
super type.

Consider this design

    interface PseudoCloseable
        /** no need to call close(),
          * unless otherwise specified, then must call close().
          * safe to call close() even if there's no need to call it.
        void close();

    interface AutoCloseable extends PseudoCloseable
        /** must call close
          * unless otherwise specified, then no need to call close()
          * safe to call close() even if there's no need to call it.
       void close();

    class ByteArrayInputStream extends Closeable
        /** has no effect
        void close();

It works as well/badly as the official design.

Zhong Yu



>
>
> Regards, Peter
>
>
>
> Zhong Yu
>
>
> whether to call close() or not. Would it work if you pass it an instance of
> AutoClosable? Never (since AutoClosable says nothing about any annotation).
>
> So I argue that MayHoldCloseableResource should be a subtype of AutoClosable
> and not the other way around.
>
> (I have not said anything about whether the MayHoldCloseableResource is
> actually needed or not.)
>
>
> Regards, Peter
>
>
>
> On 07/11/2013 10:22 PM, Paul Benedict wrote:
>
> Paul S.'s said the "negative" of using AutoCloseable is "it is no longer
> clear whether a stream should be closed or not" (6/20). That's true
> because
> the semantics of AutoCloseable indicates you have a resource that requires
> closing.
>
> However, the choice to make MayHoldCloseableResource a sub-interface of
> AutoClosable should be resisted. It's an inverted design. The Liskov
> *substitution
> principle *says that sub-interfaces can't loosen the contracts of their
> superinterface. If anything, AutoCloseable should be subclass of this new
> interface, which MIGHT hold a resource that requires closing. The current
> choice is just plainly backwards.
>
> For the above reason stated, and for the fact the interface adds no new
> functionality, it's superfluous. If the interface relationship can't be
> inverted, then chuck it -- it does nothing anyway. At the least, keep the
> annotation.
>
> Paul
>
>
> On Thu, Jul 11, 2013 at 3:01 PM, Henry Jen <henry.jen at oracle.com> wrote:
>
> On 07/11/2013 01:13 AM, Florian Weimer wrote:
>
> On 07/10/2013 11:30 PM, Henry Jen wrote:
>
> A new interface, java.util.MayHoldCloseableResource, indicates an
> implementation may or may not hold a resource need to be closed.
>
> Why doesn't close() throw Exception?
>
> Because there is really much a developer can do on that situation. The
> API simply make it not throw a *checked* exception.
>
> See EG discussion on this topic,
>
>
>
> http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-June/002081.html
>
> Annotation {@link HoldsResource} may be used to guide users/static
> analysis tools that a MHCR instance that definitely hold a Closeable
> resource.
>
> All this looks a bit odd to me.  I suppose the idea is that you don't
> want to give up the last reference to a closeable resource without
> calling close()—and not leak references which out-live the call to
> close().  This is definitely not a property of the type of the resource,
> so I don't see why the MayHoldCloseableResource interface is needed (or
> can confer relevant information).  The HoldsResource annotation could be
> useful, but based on the current documentation, it's not clear if it is
> actually intended to express the data flow property.
>
> I would suggest you look at EG discussion on this topic. The MHCR is
> different from AutoCloseable on the chances of holding critical
> resources.
>
> Perhaps that suggests the javadoc is not clear enough, I would like to
> know what is important and missing.
>
> Cheers,
> Henry
>
>
>
>



More information about the core-libs-dev mailing list