It has been a bad day... Sorry for the spam. Lesson: never type code
in a web browser.

That is probably ok for an InputStream but it is definitely not  for
an OutputStream. If there is buffering going on, flush will get called
via the close method, triggering an exception and your data would not
have been written. With your example you would never find that out.

You only want to swallow an exception thrown from close if there was
an exception from the try. There is a fair bit of code here, but you
can build a library out of this so you never have to deal with this
crap again.

class CloseException extends RuntimeException {
 final IOException closed;

 public CloseException(IOException tried, IOException closed) {
   super(tried != null ? tried : closed)
   this.closed = closed;
 }

 public IOException getClosed() { return closed; }
}

interface UsingOutputStream<T> {
 T use(OutputStream os);
}


class WithOutputStream {
 public static <T> T blah(UsingOutputStream<T> action) {
 OutputStream os = new BlahOutputStream();
 IOException tried = null;
 try {
   action.with(os);
 } catch (IOException e) {
   tried = e;
 } finally {
   close(os, tried)
 }
 }


 private static void close(OutputStream os, IOException tried) {
  try {
    os.close();
  } catch (IOException e) {
    throw new CloseException(tried, e)
  }
 }
}


To use you implement UsingOutputStream with what ever logic you want.
The similar would apply for input stream.

On Wed, Jun 3, 2009 at 3:17 PM, Mark Hibberd <[email protected]> wrote:
> Half an email. Sorry. Complete:
>
>
> That is probably ok for an InputStream but it is definitely not  for
> an OutputStream. If there is buffering going on, flush will get called
> via the close method, triggering an exception and your data would not
> have been written. With your example you would never find that out.
>
> You only want to swallow an exception thrown from close if there was
> an exception from the try. I would recommend writing something like:
>
>
> class CloseException extends RuntimeException {
>  final IOException closed;
>
>  public CloseException(IOException tried, IOException closed) {
>    super(tried)
>    this.closed = closed;
>  }
>
>  public CloseException(IOException closed) {
>    super(closed)
>
>  }
>
>  public IOException getClosed() { return closed; }
> }
>
> interface UsingOutputStream<T> {
>  T use(OutputStream os);
> }
>
>
> class WithOutputStream {
>  public static <T> T blah(UsingOutputStream<T> action) {
>  OutputStream os = new BlahOutputStream();
>  IOException tried = null;
>  try {
>    action.with(os);
>  } catch (IOException e) {
>    tried = e;
>  } finally {
>
>  }
>  }
>
>
>  private static void close(OutputStream os, IOException) {
>   try {
>     os.close();
>   } catch (IOException e) {
>     throw new RuntimeException(e);
>   }
>  }
> }
>
>
>
> On Wed, Jun 3, 2009 at 3:10 PM, Mark Hibberd <[email protected]> wrote:
>> Half an email. Sorry. Complete:
>>
>>
>> That is probably ok for an InputStream but it is definitely not  for
>> an OutputStream. If there is buffering going on, flush will get called
>> via the close method, triggering an exception and your data would not
>> have been written. With your example you would never find that out.
>>
>> You only want to swallow an exception thrown from close if there was
>> an exception from the try. I would recommend writing something like:
>>
>>
>> class WithOutputStream {
>>  public static <T> T blah(UsingOutputStream<T> action) {
>>   OutputStream os = new BlahOutputStream();
>>   try {
>>
>>   } catch {
>>
>>   } finally {
>>
>>   }
>>  }
>> }
>>
>> class
>>
>> On Wed, Jun 3, 2009 at 12:55 PM, Christian Catchpole
>> <[email protected]> wrote:
>>>
>>> Yeah, this can be a problem.  Perhaps the neatest way is to do
>>> something like this..  use a static helper which eats the exception.
>>>
>>> OutputStream os = new BlahOutputStream();
>>> try {
>>>   // do stuff hyar, hyar and hyar..
>>>   os.write( stuff );
>>> } finally {
>>>   StreamHelperThingy.closeDontThrow(os);
>>> }
>>>
>>> On Jun 3, 10:01 am, Tim <[email protected]> wrote:
>>>> In Joshua Bloch's Automatic Resource Management proposal
>>>> (http://docs.google.com/Doc?id=ddv8ts74_3fs7483dp) for project Coin he
>>>> wrote:
>>>>
>>>>     Even the "correct" idioms for manual resource management are
>>>> deficient:
>>>>     if an exception is thrown in the try block, and another when
>>>> closing the
>>>>     resource in the finally block, the second exception supplants the
>>>>     first, making it difficult to determine the real cause of the
>>>> trouble.
>>>>     In other words, by responsibly closing your resource even during
>>>> some
>>>>     catastrophic event, you can actually erase all record of the
>>>> event,
>>>>     resulting in many wasted hours of debugging. While it is possible
>>>> to
>>>>     write code to suppress the second exception in favor of the first,
>>>>     virtually no one does, as it is just too verbose. This is not a
>>>>     theoretical problem; it has greatly complicated the debugging of
>>>> large
>>>>     systems.
>>>>
>>>> I just encountered this problem: Some code threw an exception creating
>>>> a zip.
>>>> The ZipOutputStream was closed in a finally block and the real
>>>> exception
>>>> was replaced by one complaining that there were no entries in the zip.
>>>>
>>>> Does anyone do the "right" thing?  What are the best idioms or helper
>>>> methods/classes to do this?
>>> >>>
>>>
>>
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to