Some Java “Strangelets”

5 03 2007

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.

1. ignoreArgumentValue(Object)

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.

2. UndestroyableDestroyable

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.

Advertisements

Actions

Information

4 responses

6 03 2007
David Hall

In jga (0.8), #3 (w/ static imports) could be done with:

equal(sort(arr1), sort(arr2))

6 03 2007
closingbraces

David,

Heard of jga but not looked at it before. Seems quite interesting, especially in view of the current fuss over closures. Will try and fit in a quick look sometime. But without the package names, I’m not sure which jga “equal” and “sort” methods you’re referring to, as I couldn’t spot anything obvious in the jga javadoc or its index.

Anyway, even the standard JDK java.util.Arrays “equals” and “sort” would do the trick IF the objects could be sorted in a manner compatible with their own individual “equals”. That is, such that [a, c, b] and [x, y, z] are respectively sorted into (for example) [a, b, c] and [z, y, x] if a.equals(z), b.equals(y), c.equals(x).

That’s fine if you have a comparator that uses the same details as used for equals, but I’m not sure such a sort is possible for arbitrary objects with their own equals methods. (Maybe a comparator based on hashCode and some way of handling equal values with differing hashCodes? Anyone have an answer? Have a feeling I’m missing something obvious here…).

Anyway, at that point it still seems worth encapsulating into a method, so we’re just down to what the internal implementation of unorderedEquals should be (and even if a “sort” is possible, at the moment it sounds rather harder to be sure of and test than a more “manual” approach).

10 03 2007
Paul M

If you have a completely awesome little code snippet, where would you publish it?

10 03 2007
closingbraces

Paul,

Probably here first, then maybe one or more of the many snippet/tip sites. But it’d have to be pretty useful and non-obvious to seem worth publishing. Most such sites seem full of trivial examples of using APIs that are themselves quite adequately documented. They often seem incomplete or poorly coded, and ignore the alternatives, variations and trade-offs that are usually involved. Then again I don’t particularly search for snippets, just never seem to need to. So maybe I just haven’t seen the right sites yet? Any you would recommend?

No doubt some people find snippets useful, but I’d feel wasteful posting any that are just examples of normal code and API calls.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: