Saturday, September 27, 2008

Can't Hardly Wait

I ran into a wait leak issue recently and it made me wonder if there was anything I could to do prevent this issue from happening again. I found this article from a few years back written by Java performance gurus Jack Shirazi and Kirk Pepperdine. The article mainly discusses tactics for detecting wait leaks. When it comes to preventing them from happening in the first place, there's no silver bullet. Something that I thought of that wasn't mention in the article is preferring the timed wait() method instead of the no-arg version in order to prevent wait leaks. Obviously, it's not always possible to specify a wait timeout, but in situations where it is possible, it can help an application recover gracefully from a wait leak.

Tuesday, September 23, 2008

Heads and Tails

For whatever reason, tail recursion is a concept I could never quite wrap my head around. It was either something that I learned and then forgot, or heard about and never completely understood. I was reading this posting about tail recursion, Scala, and the JVM and something in my brain just clicked and it makes total sense to me now. It should come in handy when I finally get around to learning Scala.

Thursday, September 18, 2008

Compared To What?

I recently ran into an issue with the venerable Collections#sort(List) method. The List that I was sorting had an unexpected null element, which resulted in a NullPointerException during the sort. My first inclination was to change the compareTo() method to handle nulls. This didn't work, however, because of line 1157 of the Arrays#mergeSort(Object[], Object[], int, int, int) method.

1153           // Insertion sort on smallest arrays
1154           if (length < INSERTIONSORT_THRESHOLD) {
1155               for (int i=low; ilow &&
1157                            ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
1158                       swap(dest, j, j-1);
1159               return;
1160           }

The method doesn't do any null checking, so if the object on the left side of the comparison is null, a NullPointerException will ensue. Punting on this concern was probably a good idea, since the whole idea of allowing null objects in a List is controversial, nevermind figuring out where to put them in the sort order. It would have been nice if there was more information about this in the API documentation. Effective Java mentions that the compareTo() method of a Comparable type should throw a NullPointerException if it receives a null object in Item 11, but the API docs for Arrays and Comparable don't say anything about how nulls are handled.

I looked further into the Arrays class and noticed that the Comparator and Comparator-less sort methods are essentially line-by-line copies of each other, except the Comparator version uses the Comparator object to perform the comparison. I would have expected them to use the same underlying code, perhaps by creating an anonymous Comparator instance that delegates to the compareTo() method, but I digress...

I finally solved the problem by creating a Comparator that can properly handle null objects. If you ever face this problem and you're using the Google Collections library, you can use the Comparators#nullLeastOrder() or Comparators#nullGreatestOrder() methods to obtain a Comparator that can handle null objects gracefully.

Thursday, September 4, 2008

The Joy of Hex

The Java platform is so large that even experienced developers discover new classes and methods nearly every day. My discovery du jour is the 2-arg form of java.lang.Integer's parseInt() method. It's a pretty slick way to parse a hex dump, among other things.