I’ve probably wasted two hours over the last couple of days trying to debug this line of code:
private static final QName name = new QName("valid-isbn", "http://www.example.org/books");
Do you see the bug? I’ve made it even easier to find by showing you just the line that contains the bug; but it still doesn’t jump out at you. Originally, of course, I didn’t know this was the buggy line. The exception was thrown somewhere completely different in the code base, but this is indeed the buggy line.
The problem is that the arguments are swapped. This line should have been
private static final QName name = new QName("http://www.example.org/books", "valid-isbn");
This is an example of poor API design. A method should not have two arguments of the same type that can be confused for each other if you can avoid it. If you can’t avoid it, then the method should check its arguments to make sure that the right one is in the right place; and throw an exception if it isn’t.
QName class could easily have detected that I was constructing an object in an invalid state with an illegal local-name and illegal namespace URI. It should have noticed that and thrown an exception, in which case this bug would have taken 30 seconds to diagnose and another 30 seconds to fix. Instead the exception this caused didn’t happen till much later in the program, and it had a very unhelpful error message that wasn’t closely related to the real problem. Early, immediate, and obvious failure is vastly superior to delayed failure.
Interestingly this a case where even stronger typing would have helped, a lot; though doubtless the Smalltalk enthusiasts will explain to me exactly how this could never have possibly happened in their playpen; and if it did, they would have debugged it at runtime using a piece of chewing gum, a bobby pin, and a pocketknife they got out of a Crackerjack box.
FYI, XOM would have caught this error immediately and saved me hours of debugging time; but for the current project it’s necessary that I use DOM and JAXP 🙁