2009-10-25

The logically impossible is possible

In Java, how do you avoid a NullPointerException?
Easy, you test if an object equals null before trying to call any methods on it. Any idiot could tell you that.
What do you do when that null check is what is throwing your NullPointerException?
That's not so obvious ...... you fix your classpath.

So I'm running some JUnit tests in eclipse, and a particular test is throwing a NullPointerException.


Line 53's throwing NPE I think to myself, easy I'll just add a check for null. The problem was, that line was already a null check. So I fired up the debugger to try and work out what was happening. The eclipse inspect feature is great, so I put a breakpoint on line 53, and inspected the variable, yup it's null. I then inspected the null test, and it resolves to true.



So why is it throwing NPE when it's executed? What the hell is going on here?
After double and triple checking that I wasn't just going crazy, I sat back and brain stormed some possible causes for a check for null actually causing a null pointer exception.


nothing.


I've been in a similar position a few years ago; I was debugging some code and it seemed that eclipse was telling me that true == false. Yep, despite what I learned in philosophy, the logically impossible actually is physically possible. It turned out to be a combination of null values, autoboxing, default values for Booleans and eclipse's inspect function. 


With that memory I started making random changes to the variable and surrounding code, to see if anything would change the behaviour. Finally I made a change that removed the references to the null object, and found that I was still getting the NPE. This shouldn't have happened. Somehow my changes had no affect on the outcome. Then it hit me, the file I was modifying wasn't being used in the classpath. I checked my eclipse classpath, and for some bloody reason, someone had put a pre-compiled jar of the very source code I was modifying into the eclipse classpath. That jar was needed at deploy time and was built by our ant build scripts, but shouldn't be referenced by eclipse as you can just reference the project itself. I removed the jar from the classpath, and all was well.


The question is, why would the debugger take me to that source code instead of to the class file in the jar that was actually used at run time? I guess eclipse was confused by having multiple versions of a class, only one of which had source code.


I'm sure there's some kind of moral to the story here, "think outside the box", "rely on your experience", "nothing is impossible",
but it's probably something more mundane like don't screw up up your classpath or even better null is evil.