Today I had intended to write about one of the bigger things that have been bugging me recently. Like whether it’s time for a rewrite of the Servlet API; or why annotations like @NonNull and JSRs 305 and 308 are welcome but don’t go far enough; or asking how everyone tests servlet code nowadays; or my current views on closures.
But I’m not really in quite the right mood at the moment. So then I thought, to keep this blog ticking over, I’ll find some shiny little gem of code to show to the world. You know, some class or method that’s small, precise and easy to explain, but genuinely useful and not already done umpteen times over. Something fairly clever and non-obvious, but elegant rather than tricky. I must, surely, have lots of such code, because I always seem to be writing such things…
Well, I’ve had a quick hunt through my code, and have completely failed to find anything like that. Maybe that’s understandable. The code is all supposed to solve particular problems in my own particular applications, in the context of their own peculiar design forces. Anything so general and useful that it doesn’t need a long explanation is likely to already be in the JDK, or already done by someone else, or to just be a simple convenience built on top of such things (and I’ve plenty of those). Or maybe I’m just a dumb grunt coder with no original ideas and horrible code. No, surely that can’t be it!
Anyway, whilst I didn’t spot any easily-explained gems, I did find plenty of things that might look rather odd to an outsider. Not necessarily wrong, not necessarily embarrassing, not necessarily unnecessary, just rather awkward to explain. The kind of thing where your first reaction ends with a question mark, and possibly some exclamation marks too.
I’ve decided to start calling such things “strangelets” – little classes or methods that serve a useful purpose in their own particular context, but might seem strange to an impartial observer. Generally it’s the nature and purpose of the component that seems strange, rather than its actual code (the code itself is usually straightforward). To be fair, most that I’ve spotted in my own code tend to be there just to support testing, which can often require a few contortions and jumping through hoops.
So, at the risk of trashing whatever little reputation I might have left, here are a few example “strangelets” from my current projects. I’m hoping these aren’t really so strange after all, but do feel free to laugh, cry, wince, curse, argue, or otherwise comment – or even make me feel a bit better by admitting to some strangelets of your own.
This is an empty method that takes a single argument but completely ignores it.
It’s basically a work-around for some particular test-case code that violates normal code-checking rules. It’s used in a tiny number of test cases where an example subclass of something needs to be declared, and the test needs it to provide specific constructors with particular arguments, but the arguments aren’t actually used and their values are irrelevant for the test. The problem is that for constructors, code-checking tools tend to (quite rightly) report unused arguments as a mistake, given that constructors can’t be overridden. Such situations are very rare, but I have come across some – like when using reflection to access a class’s constructors, with example subclasses being used to test the handling of different types and combinations of constructors.
There are obviously many other ways around this, but it seems simple and explicit to have a call to an “ignoreArgumentValue” method. It satisfies the code-checking tools, and documents the fact that the argument is deliberately present but not used. OK, maybe I’m just kind of tickled by the idea of a method whose only purpose is to ignore its argument.
For testing of error handling, I’ve found it useful to have ready-made InputStream classes that always throw an exception from particular methods. So I have an “UnreadableInputStream” whose read method always throws an IOException, an “UncloseableInputStream” whose close method always throws an IOException, and so on. It’s then very easy to test the exception-handling code of methods that operate on InputStreams. Similarly for OutputStream and other such interfaces… including an “UndestroyableDestroyable” class.
3. unorderedEquals(Object, Object)
Arrays seem to be rather second-class citizens these days, overtaken by collections and generics and not really mixing with them all that well. But they are so ingrained in the language, and have such easy-to-use syntax, that it’s hard to avoid using them. Then there is all the legacy code and APIs that use arrays. Despite all the JDK methods for dealing with arrays, it’s not always obvious what can and can’t be done or how best to do it, and every now and then you hit something that isn’t straightforward. So over time I’ve accumulated a handful of odd little routines for doing things to arrays or “smoothing over” their interaction with Collections and even Enumerations (as still used in the Servlet API). A potentially rich source of strangelets.
One example is a static “unorderedEquals” method that takes two Object arrays and compares their elements for equality whilst ignoring the order in which they appear in each array (for example, such that [a, b, c, b] and [b, b, c, a] are regarded as equal). This seems a bit strange because the order of elements in an array is usually relevant, and even where not you could usually use Arrays.asList to turn the array into a List and then turn that into a Set (or whatever) to achieve an appropriate “equals”. But in this particular case somebody else’s API was returning me arrays of arbitrary objects, with various “equals” implementations, in an unspecified order and potentially including duplicates, and I needed to compare such arrays for “equality”.
Turning the array into a Set wouldn’t deal with differing numbers of duplicates (e.g. [a, b, b] vs [a, a, b]). A bag (or “multiset”) would do the trick, but the JDK doesn’t provide one. The Apache Jakarta Commons Collections library provides a Bag interface and implementations, but it didn’t look that promising at the time (“violates the Collection contract”…”exercise caution”…), and also seemed like overkill for this specific requirement. So I ended up writing my own little “unorderedEquals” method, to do a bag-like comparison of the array contents.