About a year ago I patched my own log4j to fix the fact that it can swallow
InterruptedIOException. Then I filed a bug against log4j, and got into an email conversation with Curt Arnold, who rightly pointed out that there were other scenarios where
InterruptedExceptioncould be easily ignored. Anything that wraps an
InterruptedIOExceptionand rethrows something that doesn’t derive from them is effectively ignoring the intended effect of a thread interrupt. The most common examples of this are
java.lang.reflect.Constructor.newInstancewhich both throw
java.lang.reflect.InvocationTargetException, which can have this problem.
The title of this post may be a bit misleading;
java.io.InterruptedIOExceptiondoesn’t cause this problem, it just makes it at least twice as difficult, because you must always check for both
InterruptedIOExceptionin wrapped exceptions. But it also means that any method that throws
java.io.IOExceptionmust have special handlers for an interrupted thread.
I tried to find a bug in Sun’s database that warns about
InterruptedIOExceptionand these cases, but the closest I could find was Sun bug 4385444. That doesn’t really have anything to do with it.
When I first saw the changes made for
java.niofor interruptible IO, I thought the use of
InterruptedIOExceptionwas clever and elegant. But because of the very special nature of
InterruptedException, I changed my mind—of course, there wasn’t much option, because
java.niointegrates with existing
java.iointerfaces and methods which already do not throw
InterruptedException, therefore they had to follow that path. It’s really a difficult situation; it isn’t the first case in Java of a hidden or wrapped
InterruptedException, it just makes it more widespread. Now you have to handle an interrupted thread anywhere
Note that on Solaris (x86 and Sparc)
java.iomethods can also throw
InterruptedIOException. You don’t need to use
java.nioto see this effect. On other platforms you only have to worry about this if you (or things you call) use
I’ve come to the conclusion that thread interrupts are so special, and currently so difficult to deal with, that Java should treat
InterruptedExceptionas a third type of exception: one that is implicitly thrown from every method. Of course this opens up its own can of worms, not to mention that it’s about 15 years too late to make such a change.
This also speaks to the fact that you should be following a pattern where it’s rare that you catch exceptions that you don’t understand, and should be catching them as far up as possible, where you can centralize your exception handling. I think this is also a good case for frameworks like Spring and Seam which use AoP; each method invocation can have a carefully thought out exception handler, either via your own AoP, or directly handled in the framework.