Point lambdafications in java.io

Remi Forax forax at univ-mlv.fr
Mon Jun 24 00:40:21 PDT 2013


On 06/23/2013 02:46 PM, Stephan Herrmann wrote:
>>>> I am not sure we have the same understanding of the word "can't" :)
>>>> This is definitely a valid concern (thanks for raising it!), but it's
>>>> a long way from there to "can't."
>>>
>>> I you prefer, you can translate "can't" to "It will be very annoying at
>>> least 1,643,467 developers*".
>>
>> Yes, that's a better translation :)
>>
>> A reasonable course of action here is to work with the IDE vendors on
>> this to refine their detectors.  They're even all represented here!
>
> I'm the maintainer of static analysis in the Eclipse compiler and I'm the
> author of the particular analysis discussed here.
>
> Brian and I had a brief discussion via email and here's my 2c to add to
> the discussion:
>
> In an ideal world (=simple enough to obviously have no errors)
> the contract of AutoCloseable would always indicate necessity to close.
> Easiest for tools and: easiest for users.
>
> Already in Java 7 static analysis needs to know about several exceptions
> in order to be useful in real world use. To accommodate this the Eclipse
> compiler already uses three white lists:
> - "resource-free" closeables (e.g., ByteArrayInputStream)
> - wrapper closeables (e.g., BufferedInputStream)
> - 3rd party utilities for closing (e.g., apache's IOUtils.closeQuietly)
> And yes, the analysis invests efforts to handle the interactions between
> these.
>
> Already at this level it becomes clear that just one interface is not
> enough to specify the responsibility to call close(), a JSR 308-based
> extended type system is the natural road to capture responsibilities
> and effects.

No it's no natural at all :)
JSR308 annotations work well to express metadata on *value*
like @NonNull by example but doesn't work well on *object* (or object state)
apart if you consider the C++ const annotation as a good design.

>
> For Java 8, adding one more explicit exception to the leak analysis
> is not a big deal. Obviously, completely excluding Stream from this
> analysis would be a significant loss in accuracy, not being able to
> track, e.g., the GCR resources from Files.walk() would be a pity.
> For that reason I strongly suggest to also document the exceptions from
> this exception, viz. the API that are known to produce a Stream that
> does own one or more GCR resources.
> Given this information I can adjust the analysis of the Eclipse compiler
> to work well with the Java 8 libraries.
>
> I hope this settles the issue of "can't" concerning static analysis.
> I'm not in the position to judge how *users* will find their way to
> knowing which AutoCloseables really need closing and which ones don't...

So the solution you propose is to make Stream extends AutoClosable and
document if the stream needs to be closed or not and you will hard code
this in the staic analysis of Eclipse.
I don't think it's a good idea because unlike Reader, most of the Stream
implementations doesn't need to be closed by default. And you can not
decide that the analysis should not warn if an unknown Stream is used
because not emitting a warning is not the safe choice.

I don't think we should bother users with the fact that the source of a 
stream
need to be closed or not. It's a property of the source, so it should be
something known by the Spliterator. So I propose to add a method close()
to the Spliterator that should be called once at the end of the iteration.
The issue of this idea is that it breaks a useful invariant that you can use
a Spliterator without knowning if its a top-level one or one returned by 
trySplit,
but I don't think it's a serious issue.
If the fact that the resource need to be closed is encoded in the 
Spliterator,
users can use all streams without caring if the resource need to be 
cleaned or not.

For Eclipse and all other static analysis tools, it needs to recognize 
in the Stream API,
what are the terminal operations and be sure that locally either the 
Stream escape
or a terminal operation is called on it. Because a terminal operation 
will calls
the method close on the Spliterator, the problem is solved.

>
> HTH,
> Stephan
>
>
>

cheers,
Rémi



More information about the lambda-libs-spec-experts mailing list