Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java I/O Annoyances: Method to the Madness

DZone's Guide to

Java I/O Annoyances: Method to the Madness

Having Java I/O problems? Yeah, it happens. Here's a glance at a Java I/O exception problem, and why it's occurring.

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

While making some updates to HTTP-RPC the other day, I discovered a couple of potentially confusing features of the java.io package that I wasn't previously aware of:

#1: The PrintStream and PrintWriter classes consume exceptions. From the PrintWriter documentation:

"Methods in this class never throw I/O exceptions, although some of its constructors may. The client may inquire as to whether any errors have occurred by invoking checkError()."

Because I had incorrectly assumed that a PrintWriter would propagate any exceptions thrown by the underlying stream, I hadn't been calling checkError(). The result was that HTTP-RPC's RequestDispatcherServlet class, which writes response data to the PrintWriter instance returned by ServletResponse#getWriter(), failed to detect when a connection had been terminated by the client. The servlet simply continued writing to the output stream. Once I started calling checkError(), the response was correctly terminated:

if (writer.checkError()) {
    throw new IOException("Error writing to output stream.");
}

I couldn't find any explanation as to why these two classes were written this way, while all of the other classes in java.io appear to simply propagate exceptions.

#2: The read(byte[], int, int) method of the InputStream class also consumes exceptions. From the Javadoc:

"The read(b, off, len) method for class InputStream simply calls the method read() repeatedly. If the first such call results in an IOException, that exception is returned from the call to the read(b, off, len) method. If any subsequent call to read() results in a IOException, the exception is caught and treated as if it were end of file."

This is extremely misleading, since it completely obscures the fact that an error occurred and makes it appear as though the stream terminated normally.

So, even though this behavior is not what I had expected, at least it is documented, and is something I'll now be aware of when using these classes in the future.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java ,io ,devlife

Published at DZone with permission of Greg Brown, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}