What’s Wrong With … Exceptions

29. June, 2007

Do you know what checked exceptions are for? They are one of the main features of Java, yet many people don’t how when to use checked or runtime exceptions. Sadly, this is not only true for beginners, who are regularly confused by this topic, but also Java professionals. Moreover, when the topic comes up, a heated discussion flares up between the pro and the against groups. I’ll call them the vi and emacs groups, because they behave so similarly.

The vi group wants to get things done. Their tools must be simple, solid, always available. They despise checked exceptions because they feel they get in the way. The Emacs group, on the other hand, likes the comfy, all-encompassing tools, that read your lips and bring you coffee. For them, checked exceptions are a way to build more robust software.

I’m in the vi group. I’ve never bought the idea that checked exceptions make software more solid just as I don’t believe that laws reduce crime, but that’s another story. First, let us look at what checked exceptions really are. For the sake of your sanity, I omit java.lang.Error.

When Java was developed, C++ was all the hype. C++ had this thing called exceptions which could be used to report unusual (= exceptional) states. The Java designers looked at them and found that you could use them for two purposes: Error and exception handling. Errors are, unlike exceptions, expected states. When I open a file and the file doesn’t exist, that’s an error. When a user is asked for some info and that info is obviously wrong (text instead of a number), that’s an error. Errors happen outside the scope of your program. They are likely to happen and it makes sense to handle the error by, for example, showing a dialog to the user so she can solve the problem and there is a high chance that she can actually do it.

Exceptions are unexpected. They happen within the scope of the program but there is probably nothing you can do anymore after the problem happened. Null pointers are the standard example. When the program tries to follow a reference and that reference is null, what can it do? Obviously, something must be broken elsewhere but more often than not, there is nothing that could be done to fix the problem when it happens. Except maybe display a death message and crash.

The Java designers decided to invent checked exceptions to denote errors, illegal and unexpected states outside of the scope of your program. Let’s look at what they came up with:

FileNotFoundException is checked (correct).
IOException (harddisk dies) is checked, too (correct but not very intuitive: What can the program possibly do when this happens?).
SQLException which can mean your DB connection just died because the DB server was rebooted (error) or you tried to insert data twice (exception) is checked, so it’s right sometimes, sometimes, it’s wrong; Oracle folds some 50’000 errors into SQLException; some are exceptions, some are errors according to the defintion.
IllegalArgumentException (when you pass wrong arguments to a method) is not checked (correct).
ClassCastException is not checked (correct).
ClassNotFoundException is checked; I believe this is wrong since the classpath is within the scope of the program and there is not a big chance that recovery is possible.

So as you can see, even the designers of the language were also confused when to use errors or exceptions (or they dreaded the amount of code that would have to be written if they had used an error). But it goes on: Checked exceptions must be handled. If you don’t do anything, the compiler will stubbornly refuse compile your code even though nothing is wrong with it. The code would work! It’s not like a syntax error or something. The compiler just bullies you. So especially beginners (who have to juggle all these many new things in their heads) are challenged how to handle them. Some add the necessary throws statements to their methods until they have 20 of them in the method definition and they give up. Here are a few common patterns what happens next:

void foo1() throws Exception { ... }

void foo2() {
  try { ... } catch (Exception ignore) { }
}

void foo3() {
  try { ...
  } catch (Exception e) {
    e.printStackTrace();
  }
}

void foo4() {
  try { ...
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

void foo5() {
  try { ...
  } catch (Exception e) {
    throw new RuntimeException("Something was wrong");
  }
}

There are many problems with these approaches:

  1. foo1() hides which exceptions can be thrown, so there is no way to handle them higher up even if you could. The compiler won’t allow you to add specific catch statements (because these exceptions aren’t thrown anymore), you will have to catch Exception and then use instanceof and cast. Ugly at best.
  2. foo2() just swallows all exceptions, runtime and checked. They are just gone! The code will start to behave erratically and there is no way to figure out why except using FindBugs or your eyeballs. Have you ever tried to find such a bug in 20’000 lines of code?
  3. foo3() seems to be an improvement but it isn’t: Instead of having a notification when a problem happened, someone (a human) has to control the output of the code manually. This doesn’t get better when the exception is sent to some logging tool, because they usually also don’t notify someone on their own (who wants to get 10’000 emails if something breaks in a loop?), so I omitted this case.
  4. foo4() is most often used but it’s no solution, either: All exceptions are again folded into one (so you can’t say anymore which could happen and react accordingly) and RuntimeExceptions are wrapped (because they extend Exception) even though that is unnecessary.
  5. foo5() is my favorite. “Something” is wrong. Really? What? How do I find out after the fact? How do I test that my bugfix in fact fixes the problem?

If you think only beginner make these mistakes, then search the JDK. You can find plenty of examples for each of these. It’s not a mistake, it’s the standard response of developers when they use a feature which is not well-understood.

What can be done?

Many of the Java frameworks gave up on checked exceptions and converted all their code to use runtime exceptions instead. Spring and Hibernate are the most prominent examples, especially since they had such a huge codebase to fix. They probably put a lot of thought into that before investing countless hours into rewriting all the exception handling code and imposing the same work on all their clients.

Maybe this is the best solution since Sun will probably not modify their compiler (and it’s only the compiler that needs to be fixed! The Java runtime, the VM, does not care about missing catch and throws statements). Unfortunately, this leaves a large gap. Personally, I don’t hate checked exceptions, I hate that the compiler insists on knowing when I can handle them. I also hate that the compiler hides half (or more) of the exceptions that could be thrown in a given piece of code from me. I have to compile the code in my head to get that information which is wrong for any reason. In both cases, the compiler (or the guy who wrote it) makes assumptions on what I can do where in my code or tries to impose limitations on me that make sense for him.

What I would like to see is this: The compiler should collect all the exception information it can get and add that to the throws clause in the .class file (you can add runtime exceptions to the throws clause, you knew that, didn’t you?). There are very strict rules what Java code can throw where, so this should be hard but not impossible. True, this will never be perfect but I’m only asking for best effort here. Next, it should not complain when an exception is not handled anywhere. Sounds like a sure recipe for a painful death but bear with me.

In the IDE, I would like to have a tool which allows me to see and filter all these exceptions. I would like to see all SQLExceptions that my DB code can throw. Ideally, I would like to see all the possible error codes as well (I’m dreaming here but you get the idea).

The goal is to have tool support for handling any number (from 0 to 100%) of exceptions that could occur based on my needs. There is a big difference whether I whip up some run-once tool for myself that scratches an urgent itch or whether I write a framework or code for a nuclear power plant.

Right now, the compiler is doing the wrong thing for everyone. That is bad.

Moreover, when you’re doing Test Driven Development (like I do and you should), then having the compiler enforce error handling becomes a real nuisance since your tests will check both the correct and the error cases. In that regard, the error handling in your code will always be the best that could be there. And if you look at this from the economical side, there is no point in handling an error that never happens (even if it could): The more rarely an error occurs, the more it becomes an exception.

More info: Java’s checked exceptions were a mistake” by Rod Waldhoff and “Removing Language Features?” by Neil Gafter. These are just two examples of many you can find on the net. If you want to see a reason why nobody gets it right, have a look at Chapter 11: Exceptions of the Java Language Specification or “Unchecked Exceptions – The Controversy“.


What’s Wrong With … CSS?

28. February, 2006

As an internet enthusiast, you will sooner or later get in contact with one of these greater evils: XHTML, JavaScript and CSS.

You will find the css Zen Garden, be baffled at what can be achieved with pure CSS and, typical for something evil, be lured into it’s fangs.

Suddenly, adhering to W3C standards will become an important goal. Even if there is no browser which can display all of the W3C standard. Most of the users use a browser, which specifically doesn’t support the W3C. Of course, the produce of said product will pledge differently but in the end, what matters is what you can see on the screen.

It ain’t pretty.

After you get your HTML to validate — which means you have already lost countless hours to fulfill a simple several-thousand-page international standard — and you can finally proudly add the XHTML DOCTYPE at the top of your page.

Now, some simple stylesheet to please the eye and you’re ready for the world.

Two weeks later, you find yourself confronted with two choices: You can either concede and show the world that you failed to find an optimum between the deficiencies of the CSS standard and the bugs and incompatibilities of just the two main browsers by publishing another dull website.

Or you can show that you simply don’t care and publish something which looks good on just your computer.

Eventually, one of your friends will tell you what they are snickering about when you show up.

When I saw XHTML and CSS for the first time, I hoped that it would solve some or even many of the problems we have today.

Instead, they made everything worse.

Absolute positioning of elements is relative. What’s so great about strong that the simple b was dropped? With CSS, the name of the element shouldn’t matter anymore.

Instead, we have roughly 200 styles. Many of them are actually supported by a few web browser and some of those are supported correctly.

When I want to emphasise something, Blogger.com wrestles this into my text: &ltspan style=”font-style:italic;”>correctly</span>

Excuse me? <em>correctly</em> should do, shouldn’t it? What will the blind think?

I bought several books about CSS. They all share these common traits: A list of all styles, each with a table when it doesn’t work. A very big number of pages how to work around the most important browser bugs (search A List Apart for “box model”).

After several years, even the most hard headed CSS evangelist finally admits that some layout problems can still only be solved by using tables.

If you want a div to have a very definitive width and a margin around it, you must use voice-styles to confuse the browsers which get it wrong. Or use negative margins. Float it. Nest several divs. All but position it absolutely relative to a hidden element which must contain a flash animation.

The many CSS resources on the net show every day that you can achieve incredible designs with CSS.

FCKeditor is created by some smart minds. At home, it works. At work, I don’t get a toolbar.

I just want my div not to shrink too much because the content becomes a tad unreadable at 30pt. There is a style for that but it’s not supported by anyone. Or there are scroll bars that I don’t want. Or my readers with their new shiny 1920×1600 LCD screen are locked in a 300×256 postcard (all measurements in pixels).

Everybody screams test driven development today. Why is there no test suite for CSS and XHTML with PNG images how is has to render?

No further confusion how to interpret “padding, border, and margin areas”.

But it doesn’t even start to become a solution to the actual problem: Separate content from display.

I don’t care about “strong” or “b” or <span style=”font-style:bold;”> or <span class=”bold”>. It looks the same to the reader.

When I want to publish something on the net, I want to create a meta language. I want to use XML to specify “this is something someone said”. I want to be able to create new tags and then give them meaning (this will lead to the semantic web) and then give them a presentation.

I want a style sheet which defines new elements and how they look on the screen. I want to be able to say “all these elements are top aligned” without having to put them into the same container.

I want to be able to reuse the work of some greater design genius without having to worry about new browser versions. Without forcing my readers to enable JavaScript just to be able to visit my pages (read that is, not interact with them).

I want something like vex. Unfortunately, this project seems to be all but dead.