Checked or unchecked?

Exception handling model in Java requires that all checked Exceptions (deriving from java.lang.Exception) are either caught or declared in the throws clause of the method where it is thrown. Compiler checks that this rule is followed and generates a compile-time error when it is not. Exceptions deriving from java.lang.RuntimeException are called unchecked since they do not have to be declared and compiler does not check for them.

The checked/unchecked dichotomy has been around since the invention of Java. Then, late in 1990-s Microsoft decided it liked Java, but wanted to own language. So they created C#, which was very much like Java, but with some improvements. Not surprisingly and in a typical Microsoft way, they did away with checked exceptions altogether. In C#, all exceptions are unchecked. Method signature says nothing about exceptions that can be thrown by the method. There is no throws clause, so there is no way to describe which exceptions a method may throw. At the first glance, it makes things easier: developers do not need to write code to deal with exceptions. This is also the problem: developers have no way of knowing which exceptions may be thrown by a method. Even if they have access to the source code of the method, it is still not enough: one needs access to the source code for all nested calls.

Since the release of C#, a vocal minority in the Java world has been advocating for adopting the same approach: doing away with checked Exceptions. While this position is rightly considered extreme, the choice between using checked and unchecked exceptions needs to be made every single time you create your own Exception class or write code throwing an Exception.

The debate about the proper place to draw the line between checked and unchecked has been ongoing in the Java community. I can not presume to cover the entire Java universe, but I’d offer my perspective as a Web and enterprise middleware architect and developer. While wholesale abolition of checked Exceptions is out of question, the boundary between the 2 classes and their appropriate usage is decided for each project. Let’s consider some approaches to drawing this boundary.

In a typical Web application, every Web requests requires access to some kind of backend (database, mainframe, etc). External resource access is by its nature “exposed to elements” over which our application has no control (a network outage, data center flooding, partner application down, database server overheating, etc). That’s why Java methods that implement external access always throw a checked exception, such as IOException or SQLException. In a large and stable application, exception processing is generalized in an exception handling framework, which may be responsible for the following:

  1. insulate end user from technical details of unexpected errors that are of no benefit to him, and facilitate presentment of a clean notification of an internal problem
  2. enable quick detection and remediation of infrastructure failures (out of disk space, lost database connection)
  3. collect and preserve exception information to aid troubleshooting and debugging
  4. record failed transaction outcome for traceability/auditing

With this in mind, I will explore 2 very different approaches to deciding on checked vs unchecked exceptions. First, let’s turn our attention to this Elliote Rusty Harold’s article. He suggests that we should start calling checked exceptions “external exceptions” and runtime exceptions “internal exceptions”.

If the exception is caused by problems internal to the program, it’s a runtime exception. If it’s caused by problems external to the program, it’s a checked exception.
Short, simple, to the point. Are there any exceptions to this rule? Are there any cases where an internal program bug legitimately should be signaled by a checked exception or a problem in the external environment should be signaled by a runtime exception? I can’t think of any.

I think this is a wrong way to draw the line, at least in a typical Web or middleware application.

It is true that in most situations where an external system access occurs, a checked Exception is usually thrown – most frequently an IOException or a SQLException. Let’s explore a bit more. What would cause a SQLException? Usually a program bug (unsatisfied constraint, failed to check for maximum field length, wrong table name) or an infrastructure problem (connection lost, out of disk space). Theoretically you could also use SQLException to signal a business condition (record with this ID already exists), but this is widely recognized anti-pattern and I hope you are not following it. So we are left with situations that do not allow successful completion of processing (program bug or infrastructure failure).

What do you do in response to a checked Exception in this situation? In my experience, individualized exception handling logic specific to a method is highly unusual. You can not fix a program bug programmatically and you normally can not work around an infrastructure failure or misconfiguration. To wit: if a checking account balance request returns a RemoteException, there is nothing you can do in your Web application to recover from this situation and still show account balance to the end user. You can only say “Sorry” in a nice way as prescribed by your application coding standards. Same if you try to retrieve order shipment details and SQLException comes back. And so on.

As a sidebar, once we’ve established that exception processing is generalized and boilerplate, we could call it a cross-cutting concern, and engage in some Aspect-Oriented Programming.

A typical generic exception handling code implementation that I’ve seen wraps original Exception in MyCompanyException and propagates the latter all the way down the call stack without examination or processing in intermediate layers. This pattern is widely accepted and generally makes sense, but it is not perfect. One thing that immediately jumps out at you is that almost every method in your application now throws MyCompanyException. This is so because Web and middleware applications exist to process data stored in different kinds of backend systems and methods for accessing those systems invariably have a chance to fail, so they throw a checked Exception (e.g. SQLException for databases). The typical approach described above propagates these Exceptions back in the form of checked MyCompanyException. This presents a glaring problem: signal overload. When everyone is a suspect, you do not really have one. If every method throws the same checked Exception, the “throws” clause adds no value, only overhead. You might as well close the book on checked Exceptions and go home – make MyCompanyException unchecked.

What can a developer do in this situation? Why would I want every programmer to worry about infrastructure problems, even at a trivial level (inserting standard calls for exception processing)? Most programmers should focus on implementing business logic. Java community built numerous frameworks that externalize “technical” concerns, remove the need for repetitive code and free the programmers to focus on the business problem at hand. This is one of the reasons Java development is productive enough to be a market success.

I should mention that Elliotte Harold, the author of the blog post I’ve discussed above, has become kind of an “unchecked exceptions skeptic”. He recently published an article on IBM developerWorks devoted specifically to avoiding throwing a RuntimeException. He goes to a great length and writes quite a bit of code to achieve that. He even implements his own bubble sort! Here’s what I don’t like about that. First, the more code one writes, the higher a chance of a bug. Second, when someone reimplements system functionality, there is an added risk of creating an inferior solution. This adds up to a steep price, so the author must believe unchecked Exceptions to be a very dangerous thing to justify this high price. I am among of those who disagree and find unchecked Exceptions a useful tool. In fact, I advocate a wider use of unchecked Exceptions in the domain of Java I’m familiar with.

For comparison, let’s look at what Tata’s ShriKant Vashishtha advocated a few years back in this artcile:

Exceptions for which the end user cannot take any useful action should be made unchecked. For example, exceptions that are fatal and unrecoverable should be made unchecked. There is no point in making XMLParseException (thrown while parsing an XML file) checked, as the only action to be taken may be to fix the root cause based on the exception trace.

This is the crux of his article. He devotes the rest of it to elaborating how this pattern would work with Struts.
I find this approach more reasonable. The difference between checked and unchecked is that developer is forces to “do something” about checked Exceptions. If a developer can not do something meaningful, this “doing something” becomes nothing but waste.

Combining ShriKant’s idea with an observation that most external access Exceptions switch the code execution over to the “sorry” path, I suggest an expanded usage of unchecked exceptions. Unless there are individualized exception processing / recovery possibilities, take checked Exception thrown by the code accessing an external system and quickly turn it into a RuntimeException, right at the point where original Exception is realized. This would eliminate useless and distracting “throws MyCompanyException” clauses all over your code. You will then need to remember to catch RuntimeException in the outer layer of your code (in Struts, a Front Controller) and decide what to do with it. In an extreme case, you can even ignore it and let container handle it. Web Containers catch all Runtime Exceptions and give developers some limited configuration options for dealing with those (error page). Of course, true business exceptions (such as failed input validation) would be exempted from this policy and would remain checked Exceptions, forcing developers to handle them explicitly.

You may ask: what about monitoring/infrastructure related goals of Exception handling framework (“quick detection and remediation of infrastructure failures” I mentioned above)? Since this is a cross-cutting concern that applies universally to all applications running in a particular server environment, it would be better to handle error detection and notification by server infrastructure independently from application code. This would free programmers from having to worry about it and increase reliability of the code (detection/notification happens automatically and does not depend on programmer remembering to insert right code). It is certainly possible. For example, when using IBM WebSphere, one would leverage FFDC for error detection and build a solution on top of that.

UPDATE 11/8 in response to Elliotte’s comment below.
Key point that Elliotte makes is that local error handler is preferable to a global error handler because it has context: information about specifics of the situation that resulted in an error. He also addresses the point that global error handler would often find itself in “nothing I can do here” position when trying to handle an error. But I was trying a completely different point: that local error handler is often times in no position to take a meaningful action, despite having the local context. Thus responsibility for handling the error may be safely transferred to a global handler. Even if you know precisely what you’re trying to do, most errors will break the “happy path” irreparably. In most cases, after an error, the difference may be in the tone of “Sorry” you say, but you will never be able to answer the original question (client request). Situations where a retry is reasonable excluded, obviously.

This point makes sense if you assume a separation of responsibilities that makes application code focus on the task at hand and leave infrastructure concerns to “others”. Please stay with me for an explanation.

It doesn’t know … whether the sys admin needs to be woken up at 3:00 AM in the morning or not

No, no. I don’t want local error handler to figure whether the error is so truly fatal to the functioning of the whole application that it requires an immediate attention. And don’t get me wrong – I don’t want global error handler to be responsible for that, either. I alluded to my preferred answer to this problem in the last paragraph of the original post – externalize this logic. To ensure reliable run of your application, you should monitor it. Monitoring would include intercepting and collecting exception information. Your monitoring software will then be configured to react appropriately to situations you are interested in. You achieve a separation of concerns: Java code in your application is concerned with solving the business problem at hand, while monitoring configuration defines reactions to system errors (including sending pages to sys admin staff).

Suppress MQJE001 in System.err log output when an MQException occurs

When you use WebSphere MQ API for Java, exceptions in MQ layer result in a short message logged to System.err, looking like this:

MQJE001: Completion Code 2, Reason 2033

It may be quite annoying because this happens before you have a chance to catch MQException. This is especially unfortunate if the exception does not represent a true error condition in your program. This particular reason code 2033, stands for MQRC_NO_MSG_AVAILABLE and is returned when a get call with options does not find a suitable message. This may be a perfectly normal situation, e.g. for a message poller program. Is it possible to suppress this output?

Yes, it is possible, but it can only be done for one reason code at a time using static method logExclude on MQException class:

MQException.logExclude(MQException.MQRC_NO_MSG_AVAILABLE);