On trying to hide boilerplate code when using streams

For now, I’ll just copy and paste the 4 blog posts I’d written ages ago. Maybe one day I’ll just wrap it up in a simple, clear and short article. Maybe.
update: I have moved this project to GitHub and released an RC, available under groupId net.incongru on the central Maven repository. The Maven generated site is also available. Now how long will it take to make the next step ? (move/rewrite this doc, use it in a real-life project, release final version)

Part I

(Or, “Try/Catch/Finally, Closing streams, ugliness and boredom”)

I expected commons-io to do something like this, but no, they stuck with the idiotic static methods: “Close that stream, and, well, let’s ignore that exception”. What!? Sure enough, if an IOException happens when closing a stream, chances are stuff also happened while processing it, but who knows? And even then, how boring is that to keep on typing these old and idiots try/catch/finally/close the stream if it’s not null, oh wait, we need to try/catch the IOException when closing/darn we have to ignore it otherwise we’ll loose the main one. Booooring.

So, I tried to write a simple wrapper + closure to hide the ugliness of the try/catch/finally mess of safely closing an InputStream.

Let’s start with a usage sample:

new SmartInputStreamProcessor().processAndClose(in, new InputStreamProcessor() {
    public void process(InputStream in) {
        System.out.println("ah! ah! messing with my stream");
        // in.read and stuff
    }
}

Interesting ? Check the source out and tell me what you think:

package net.incongru.util.io;

import java.io.IOException;
import java.io.InputStream;

/**
 * A simple wrapper + closure to hide the ugliness of the try/catch/finally mess to close
 * an InputStream.
 *
 * @author greg
 */
public class SmartInputStreamProcessor {
    public void processAndClose(InputStream in, InputStreamProcessor processor) throws IOException {
        assert in != null;
        IOException e = null;
        try {
            processor.process(in);
        } catch (IOException processEx) {
            e = processEx;
        } finally {
            try {
                in.close();
            } catch (IOException finallyEx) {
                if (e != null) {
                    // throwing a specific exception with the process-exception nested
                    throw new IONestedException("IOException in process (" + e.getMessage() + ") but also when trying to close (" + e.getMessage() + ")", e);
                } else {
                    throw new IONestedException("Could not close stream: " + finallyEx.getMessage(), finallyEx);
                }

            }
        }
    }

    public static final class IONestedException extends IOException {
        private final IOException cause;

        public IONestedException(String message, IOException cause) {
            super(message);
            this.cause = cause;
        }

        public Throwable getCause() {
            return cause;
        }
    }
}
package net.incongru.util.io;

import java.io.IOException;
import java.io.InputStream;

/**
 *
 * @author greg
 */
public interface InputStreamProcessor {
    void process(InputStream in) throws IOException;
}

I’m having a couple of silly doubts, and it’s too late to find the answer immediately:
* The SmartInputStreamProcessor has a stupid name. Need to change it.
* I’m not sure whether the InputStream must be passed to the processAndClose method or to the c’tor of SmartInputStreamProcessor. The InputStreamProcessor instance, however, should be passed to the method, to allow the nice closure-like syntax with an anonymous inner class. (It would also be possible by passing it to the constructor, but then the method call would end up *after* the processor definition, which doesn’t seem so good looking - Oh yes, I’m into code aesthetics)

Some remarks:
* Some InputStreamProcessor might end being reusable. Pretty cool, I think.

Part II

I knew I was passing by something when writing the previous post.. Its only now that I remember the existence of these interface
Closeable and Flushable ! Of course, that could make the whole thing much more flexible !

package net.incongru.util.io;

import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;

/**
 * A simple wrapper + closure to hide the ugliness of the try/catch/finally mess to close an InputStream.
 *
 * @author greg
 * @author $Author: $ (last edit)
 * @version $Revision: $
 */
public class SmartStreamProcessor {
    public void processAndClose(final Closeable closeable, final StreamProcessor processor) throws IOException {
        assert closeable != null;
        IOException e = null;
        try {
            processor.process(closeable);
        } catch (IOException processEx) {
            e = processEx;
        } finally {
            try {
                closeable.close();
            } catch (IOException finallyEx) {
                if (e != null) {
                    // throwing a specific exception with the process-exception nested
                    throw new IONestedException("IOException in process (" + e.getMessage() + ") but also when trying to close (" + e.getMessage() + ")", e);
                } else {
                    throw new IONestedException("Could not close closeable: " + finallyEx.getMessage(), finallyEx);
                }
            }
        }
    }

    public void processFlushAndClose(final Flushable flushable, final StreamProcessor processor) throws IOException {
        assert flushable instanceof Closeable;
        processAndClose((Closeable) flushable, new StreamProcessor() {
            public void process(final Closeable c) throws IOException {
                processor.process(c);
                try {
                    ((Flushable) c).flush();
                } catch (IOException e) {
                    throw new IONestedException("Could not flush: " + e.getMessage(), e);
                }
            }
        });
    }

    public static final class IONestedException extends IOException {
        private final IOException cause;

        public IONestedException(String message, IOException cause) {
            super(message);
            this.cause = cause;
        }

        public Throwable getCause() {
            return cause;
        }
    }
}
package net.incongru.util.io;

import java.io.Closeable;
import java.io.IOException;

/**
 *
 * @author greg
 * @author $Author: $ (last edit)
 * @version $Revision: $ 
 */
public interface StreamProcessor {
    void process(final Closeable stream) throws IOException;
}

Part III

Yes, the uglyness of having to deal with IOExceptions when processing, flushing and closing streams is still bugging me. I had been tinkering with the idea of playing with generics to alleviate the pain of casting. Now I’ve just had a couple of minutes on my hands - new year’s eve’s got to be useful eh? - I finally got around to try this. I’m only partially happy because it comes to the cost of more verbosity.

I’ve also split the Flushable and Closeable processors in two distinct classes, and renamed everything, although I’m not totally happy with the new names either.

I’ll just post a sample usage and point you to the svn viewer for the actual code. Please comment, rape, steal, contribute !

final FileWriter out = new FileWriter(fullPathForOutput);
new FlushableFlusher<FileWriter>().processFlushAndClose(out, new FlowProcessor<FileWriter>() {
    public void process(final FileWriter c) {
        final XStream xStream = new XStream();
        xStream.toXML(aFooBar, out);
    }
});

So.. as we can we see, we’re a little more verbose than the sample I gave in the first post, when declaring the “Flusher” and the processor, because we have to specify our generic type, in this case a FileWriter. What we don’t see, is that we’re less verbose in the actual processing code, because in the first post’s sample, I didn’t give any real code in the process method, and if I had, it would have been showing ugly casts. I largely prefer this way, although I’d like to avoid to have to declare the generic type twice; I didn’t find a way around that, most probably because I wanted to keep a single FlowProcessor interface, and because I want to eat my own dog food in the FlusheableFlusher - which actually uses a CloseableCloser whose FlowProcessor delegates to the given FlowProcessor and then flushes the flow. (I’m using the word “flow” here to avoid confusion with the java *Stream classes, since this code works just as well with streams, Readers, Writers, and maybe even other stuff I don’t even know about which implement the Closeable and Flushable interfaces)

Now here’s the magic stuff: Main classes (well, ya, there’s a IOUtil class which has one simple stupid static method, but it basically demonstrates the genious of this AND is actually useful :p), and TestCases (not enough, ya, being lazy)

Should you not want to copy and paste the code and/or stay up-to-date with my genius nitpicking, this is part of berkano-util, and if you’re a maven user, you could add a dependency to berkano:berkano-util:SNAPSHOT in your project. Mind that this is now deployed using maven2, so I’m not sure how you could get to it using maven1. This gets regularly deployed on dist.codehaus.org which is, I believe, synch’d to ibiblio. Of course, I don’t mind if you just plainly copy the code - I should probably get my head on licenses one day, but in the meantime, just do what you want with it.

Again, please, comment, rape, steal, nitpick (this is the whole point, here), contribute ! And happy new year !

Part IV

Sounds like its time for a recap. Since I wrote these blog entries, in an in-progress-and-being-thought-about-every-now-and-then style, I’ve had comments that one actually could not figure out where I was coming and where I wanted to go to.

So, I can’t really recall when it started, but I certainly know why: being bored of having to write this:

InputStream in = ...;
try {
    // do stuff with my InputStream
} finally {
    try {
        in.close();
    } catch (IOException e) {
        // ignore... ?
    }
}

… and mostly being wondering what exactly I should do with the IOException in the finally’s catch block, when closing the InputStream. Sure enough, I won’t be able to treat that exception in most cases. Sure enough, in as many much cases, I’ll have gotten an exception before trying to close my InputStream. But still, I’m nitpicking, and I do want to know if/when this happens. Then I thought, hmm, this has to be in commons-io, right? Well, no, it’s not, they stopped at a static method that closes a stream and burries any IOException.

So that’s basically my requirements: 1) I don’t want to write all this annoying try/finally/try/catch code anymore (which I have to do even if I don’t want to treat the main IOException thrown in the first try block), 2) I don’t want to loose either of the original IOException or the IOException in finally { in.close }.

My current solution is proposed in part III, but I’m foreseeing some more changes to it: who needs checked exceptions, really? Well, let’s say that sometimes you need them, so to avoid any checked-or-not-checked exceptions debate, I’ll just write myself a couple of wrappers.. maybe just a method in each of Closer / Flusher, but I can’t think of a good name.

I’d also fancy removing the need to declare two times the type parameter (once in the Closer and once more in the IOProcessor, though it’s bound to be same), but I couldn’t really figure out how last time - which happened to be on new year’s eve, so that gives me a good excuse, should the answer be obvious.

I hope you found this sort-of-an-article interesting. Any good idea or suggestion, go ahead and comment !

See part I, part II and part III on this subject for history and some details.

edit: for you not to get lost in previous entries, please not that I renamed CloseableCloser, FlushableFlusher and FlowProcessor to Closer, Flusher and IOProcessor - thanks Mauro :)

Leave a Reply