Re: Returning external resources and Exceptions
From: Ryan Stewart (zzanNOtozz_at_gSPAMo.com)
Date: 12/15/04
- Next message: Rahsaan Page: "Re: Where are the java import files located on unix?"
- Previous message: dasickis: "Re: wondering"
- In reply to: Gerald Thaler: "Re: Returning external resources and Exceptions"
- Next in thread: Ryan Stewart: "Re: Returning external resources and Exceptions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Tue, 14 Dec 2004 20:12:41 -0600
"Gerald Thaler" <gerald.thaler@gmx.de> wrote in message
news:cpnl9e$ai0$03$1@news.t-online.com...
[...]
> I worked out several solutions. None of them is "elegant". They all have
> some ugly code duplication. I first wrote a helper method that doesnt
> throw to somewhat reduce the clutter:
[...]
> Now the code is somewhat clearer: The safeClose()-calls are only executed
> when an exception is thrown. One could also perform some additional
> cleanup (deleting the output file) before rethrowing the exception in this
> case.
>
> Nevertheless, there remains the problem of code duplication. IMHO the root
> cause of the whole debacle is that the close() methods in the API can
> throw. The same is true for most other cleanup methods in the API:
> Socket.close(), java.sql.Connection.close() ...
>
> This seems to be a serious design flaw in the API. Cleanup code that
> throws is no good. It renders the finally keyword almost useless.
> 'finally' was intended primarily as a means for reliable cleanup of
> external Resources without code duplication. But it's incompatible with
> the API. 'finally' fails big time if the cleanup code itself can throw.
>
> It's only remotely usefull if you have just one resource to cleanup:
>
> } finally {
> if (out != null)
> out.close();
> }
>
> But even then there is a slight problem, as the out.close() call may throw
> and hide the original exception (the root cause of the problem) from the
> try-body. When there is more than one resource to take care of, 'finally'
> doesn't help at all if you want to write 100% reliable code. Worse, it
> even seems to fool some developers into writing broken code that will
> swallow exceptions. I wonder wether there exists an official working
> finally-idiom/pattern!?
>
I don't know of any patterns unfortunately, and I agree that it can get
messy, but that's the way file system interaction tends to be. You might
consider a more object oriented approach. Try this on for size:
import java.io.*;
public class Converter {
protected FileInputStream in;
protected FileOutputStream out;
protected IOException exception;
public Converter(FileInputStream in, FileOutputStream out) {
this.in = in;
this.out = out;
}
public void run() throws IOException {
byte[] data;
boolean success;
do {
data = this.read();
success = this.write(convert(data));
} while (data != null && success);
cleanUp();
// If any exceptions were thrown, rethrow the first one.
if (exception != null) {
throw exception;
}
}
protected byte[] read() {
byte[] result = null;
try {
// Read whatever from your input stream
} catch (IOException ioe) {
// If first IOException, remember it.
if (exception == null) {
exception = ioe;
}
} catch (Exception e) {
// Do whatever
}
return result;
}
protected boolean write(byte[] data) {
boolean success = false;
try {
// Write whatever to your output stream
success = true;
} catch (IOException ioe) {
// If first IOException, remember it.
if (exception == null) {
exception = ioe;
}
} catch (Exception e) {
// Do whatever
}
return success;
}
protected byte[] convert(byte[] data) {
byte[] convertedData = null;
// Do whatever transformations
return convertedData;
}
protected void cleanUp() {
// Try to close the input stream. Get reference to any IOException
// if one wasn't already thrown.
try {
in.close();
} catch (IOException ioe) {
if (exception == null) {
exception = ioe;
}
} catch (Exception e) {
// Do whatever
}
// Try to close the output stream. Get reference to any IOException
// if one wasn't already thrown.
try {
out.close();
} catch (IOException ioe) {
if (exception == null) {
exception = ioe;
}
} catch (Exception e) {
// Do whatever
}
}
}
I think it will accomplish what you want. It should compile once you get
something in the try blocks that can throw IOExceptions. It's still riddled
with try/catches, but they're more dispersed. Also, you could change the
catching of Exceptions to Throwables if you're really serious.
- Next message: Rahsaan Page: "Re: Where are the java import files located on unix?"
- Previous message: dasickis: "Re: wondering"
- In reply to: Gerald Thaler: "Re: Returning external resources and Exceptions"
- Next in thread: Ryan Stewart: "Re: Returning external resources and Exceptions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|