experience trying out lambda-8-b74

Zhong Yu zhong.j.yu at gmail.com
Mon Feb 4 15:32:55 PST 2013

On Mon, Feb 4, 2013 at 5:11 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> I knew it wouldn't be long before this turned into yet another
> barely-laundered proposal to try yet again to get us to deprecate checked
> exceptions.  I get it, you find checked exceptions frustrating.  Sometimes I
> do too.  But we still believe a world without them would be worse, and we're
> not interested in pushing people towards that.

I neither hate or love checked exceptions; they are here, they are
widely used by Java applications, so we must deal with it.

> There are places in the Java libraries -- mostly from the very early days --
> where the use of checked exceptions turned out to be a mistake.  (An obvious
> example is close() throwing IOException -- what could a user possibly do to
> recover from that?)  The workarounds we're doing here are to mitigate the

(digression - failure of close() is real and is important; at least
app can tell the user that the file can't be saved, instead of
assuming otherwise)

> worst mistakes of the past, not to rewrite history.  And we're satisfied
> that this small workaround handles 90% of the 2% of cases where exceptions
> turn out to intrude in lambda libraries.  So we've made the decision to stop
> there for now, and not because it didn't occur to us to go farther.

I don't quite get it - are you saying that IOException is the 90% of
the checked exceptions, so UncheckedIOException is good enough,
instead of a more generic wrapper for arbitrary Exception.

I don't think IOException is that special. And there's nothing harmful
to make a more general UncheckedAnyException, instead of just

> On 2/4/2013 6:03 PM, Zhong Yu wrote:
>> On Mon, Feb 4, 2013 at 12:01 PM, Henry Jen <henry.jen at oracle.com> wrote:
>>> If we don't extend any exception handling or need type information, we
>>> don't really need a wrapper as Throwable already has hasCause() method.
>> UncheckedIOException is a wrapper for IOException. I'm arguing that
>> JDK should instead have a generic wrapper for Exception, so that all
>> libraries have a uniformed way of smuggling/unsmuggling checked
>> exceptions. Otherwise there are serious interoperability obstacles.
>> It appears that the lambda team does not take checked exceptions
>> seriously. It might be the right attitude academically, but real world
>> Java applications are full of checked exceptions. Without a guideline
>> from Java czars, lots of hacky ways will be invented when they try to
>> integrate with Stream.
>> Zhong Yu
>>> I recall there were discussion of transparent exception handling, which
>>> is still an open topic I believe.
>>> Cheers,
>>> Henry
>>> On Feb 2, 2013, at 9:06 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
>>>> Also, what about other checked exceptions? If I make a stream based on
>>>> JDBC ResultSet, how do I handle SQLExceptions? Should I create a
>>>> proprietary UncheckedSQLException? Should multiple libraries each
>>>> provide their own version of UncheckedXxxExceptions for every
>>>> XxxException? We'll be in this hell for some years to come before the
>>>> language gives a better device.
>>>> Meanwhile, why not provide a generic wrapper exception whose explicit
>>>> and sole purpose is to wrap another checked exception? I know the idea
>>>> is trivia, but why not?
>>>> The Wrapper can provide convenience methods like
>>>>     class Wrapper extends RuntimeException
>>>>         // if cause is E1, throw cause; otherwise throw wrapper.
>>>>         <E1> RuntimeException rethrow(Class<E1> type) throws E1, Wrapper
>>>> so we can
>>>>     catch(Wrapper w)
>>>>         throw w.rethrow(IOException.class, SQLException.class);
>>>> or to handle causes inline
>>>>     catch(Wrapper w)
>>>>         w.on(IOException.class, e->{ handle e; })
>>>>            .on(SQLException.class, e->{ handle e; });
>>>>     <Ei, Eo> Wrapper on(Class<Ei> type, ExceptionHandler<Ei,Eo>) throws
>>>> Eo;
>>>>     interface ExceptionHandler<Ei,Eo>
>>>>         void handle(Ei e) throws Eo;
>>>> obviously not elegant, but at least give us something of the sort that
>>>> can alleviate the pain in the short term.
>>>> Zhong Yu
>>>> On Fri, Feb 1, 2013 at 11:38 PM, Peter Levart <peter.levart at gmail.com>
>>>> wrote:
>>>>> On 02/02/2013 12:44 AM, Henry Jen wrote:
>>>>>> On 01/28/2013 12:16 AM, Peter Levart wrote:
>>>>>>> On 01/28/2013 12:06 AM, Henry Jen wrote:
>>>>>>>> http://cr.openjdk.java.net/~henryjen/lambda/nio.5/webrev/
>>>>>>> Hi Henry,
>>>>>>> I can imagine that many times a single block of code would be
>>>>>>> responsible for constructing a Path stream (possibly enclosed into a
>>>>>>> try-with-resources construct) and consuming it's results, so having
>>>>>>> to
>>>>>>> deal with the duality of IOException/UncheckedIOException is a
>>>>>>> complication for a user in my opinion. Wouldn't it be better also for
>>>>>>> the stream-factory methods to throw UncheckedIOException and for
>>>>>>> CloseableStream.close() to also throw UncheckedIOException (that
>>>>>>> means,
>>>>>>> only inheriting from AutoCloseable, not Closeable and co-variant-ly
>>>>>>> redefining the throws declaration):
>>>>>>> public interface CloseableStream<T> extends Stream<T>, AutoCloseable
>>>>>>> {
>>>>>>>      @Override
>>>>>>>      void close() throws UncheckedIOException;
>>>>>>> }
>>>>>> Hi Peter,
>>>>> Hi Henry,
>>>>>> Sorry for the late reply, I want to let the idea sink a little bit.
>>>>>> After couple days, I am slightly prefer not to change it because,
>>>>>> 1) The CloseableStream-factory method throws IOException reminds use
>>>>>> of
>>>>>> try-with-resource better than an unchecked exception.
>>>>> The *Closeable*Stream method return type name also reminds of that ;-)
>>>>>> 2) As factory methods throwing IOException, developer is dealing with
>>>>>> duality already.
>>>>> He is dealing with duality already *if* the factory methods are
>>>>> throwing
>>>>> IOException. If they are throwing UncheckedIOException, he is not
>>>>> dealing with duality.
>>>>>> 3) If the close method throws UncheckedIOException as the stream
>>>>>> handling, the suppressing of exceptions will be more confusing. Should
>>>>>> developer look into cause IOException or the UncheckedIOException?
>>>>> Do you think a programmer might want to handle different subtypes of
>>>>> IOException differently? If that is the case, the javadoc should
>>>>> document all the possible situations. And what about different subtypes
>>>>> of IOException wrapped by UncheckedIOException while consuming the
>>>>> stream? If the programmer already bothers to unwrap the unchecked
>>>>> exception to do the cause analisys, then this same handler would be
>>>>> good
>>>>> also for dealing with exceptions thrown in factory methods and
>>>>> CloseableStream.close(). The streams API is a higher-lever wrapper over
>>>>> the java.nio.file.DirectoryStream API and it is already wrapping the
>>>>> lower-level IOException with UncheckedIOException when consuming the
>>>>> CloseableStream. I think it should do it consistently. By doing it
>>>>> consistently, it simplifies correct exception handling logic in *all*
>>>>> situations.
>>>>>> 4) When the implementation is a Closeable, the wrapping of IOException
>>>>>> into an UncheckedIOException doesn't do any good except overhead in
>>>>>> case
>>>>>> developer want to deal with it. On the other hand, a IOException
>>>>>> handler
>>>>>> is probably in place as the factory methods throws IOException.
>>>>> It is probably in place *if* the factory methods are throwing
>>>>> IOException. If they are throwing UncheckedIOException, then such
>>>>> handler is not there. The question is whether the UncheckedIOException
>>>>> handler is in place too. If I look in one of your tests:
>>>>>   148         public void testWalk() {
>>>>>   149                 try(CloseableStream<Path> s =
>>>>> Files.walk(testFolder)) {
>>>>>   150                         Object[] actual =
>>>>> s.sorted(Comparators.naturalOrder()).toArray();
>>>>>   151                         assertEquals(actual, all);
>>>>>   152                 } catch (IOException ioe) {
>>>>>   153                         fail("Unexpected IOException");
>>>>>   154                 }
>>>>>   155         }
>>>>> You haven't bothered to handle the UncheckedIOException (because the
>>>>> test would fail anyway if it was thrown). But I'm afraid that average
>>>>> programmer will walk away from similar codes with false sense of
>>>>> confidence that he handled all exceptional situations when he put the
>>>>> checked exception handler in place. I think that being consistent and
>>>>> throwing UncheckedIOException everywhere would actually have greater
>>>>> probability for average programmer to not miss the handling of
>>>>> exceptional situations while consuming the stream - at least all
>>>>> exceptional situations would be handled or not handled equally.
>>>>> Regards, Peter
>>>>>> Does it make sense?
>>>>>> I updated the webrev to have some test coverage for exception
>>>>>> handling,
>>>>>> it's painful as always, but the duality is not what bothers me.
>>>>>> http://cr.openjdk.java.net/~henryjen/lambda/nio.6/webrev/
>>>>>> Cheers,
>>>>>> Henry

More information about the lambda-dev mailing list