Archive | java
The Accidental Feature
My manager was able to squeeze in another last-minute feature into this sprint. When he told me what it was, I wasn’t too happy about it. That part of the code isn’t the greatest, and I knew that we have some issues in that part of the functionality anyway. I scheduled about 3 days for that task, which is quite a long time for me.
So, this morning, I decided to get it over with. Thought about just changing the code, and I decided that I needed to walk the talk and wrote the unit test first. I ran it, thinking that things would go up in flames. The results shocked me.
The test pass. The feature was already there!!
I wasn’t sure how or why. I took a look at the code and figured that it was wrong it how it did things, but it must have been wrong in the right way. Or two wrongs made a right or something, because the feature was already in there. I decided that I shouldn’t just cross all three days off my list, but instead cleaned the code up some, re-ran my test and it still worked. So I checked it in and I was done.
Thus is the beauty of Test-Driven Development — you know when you are done. And, with the unit test checked in, I knew that the Accidental Feature would always work.
Even when it shouldn’t.
The Ghost Classes of Cobertura
We use Cobertura inside our continuous integration system and I have spent the last two hours trying to figure out why a couple value objects where showing 0% coverage because, you know, they actually had tests written for them. Because I just wrote the tests!
After some investigation, I discovered the packages of these objects were different — the classes I wrote the tests for were in the vo package and the classes that had no coverage were in the beans package. I looked a the Cobertura report for the vo package and — heck — I had 100% coverage!! And there were no beans package for this project. Things just got a whole lot weirder.
I poked and prodded and figured out what was happening. It turns out that these objects were once in the beans package, but then got renamed to vo (which is our standard package for business objects). However, whoever refactored the classes didn’t refactor the tests with them. So there were still tests in the beans package that called the classes in vo. But this confused Cobertura, because it (rightfully) thought that there should be test for the beans package.
Interestingly enough, the ghost classes still showed up after I delete the rogue tests from SVN. I had to manually go into our CI server and do an “ant clean” to stop JUnit and Cobertura from reporting on them.
Is this a bug in Cobertura? Kinda, technically, maybe. But it’s actually a problem with how this was refactored. If you refactor you objects to a new package, remember to move your tests as well!!
An example of Intellij’s coolness
So I was coding away in Intellij, and did my Ctrl-Click thing to bring up a method in another class, and look what I see:
So I click on “Update Project”, I get the latest from SVN, and I move on with my life.
This, my friends, is coding bliss.
I’m a No-Fluffer
I sacrificed my weekend to attend Omaha’s No Fluff Just Stuff. And I had a great time. Some of my highlights:
- I saw most of Ken Sipe’s talks, mostly because everything he talked about was applicable to me. My favorites of his were Iteration 0 (starting off on an Agile project) and the Scalability talk.
- Everyone in the room was awed by Alex Miller’s Terracotta talk. Terracotta is very, very cool stuff. Miller’s Collections talk was also very good. It wasn’t quite what I expected it to be, but that was a good thing. But Big-O doesn’t scare me.
- If you are ever at a conference with Ted Neward, you need to hear him speak. Seriously. Even if you don’t think you care about the subject, you need the experience. I learned tons from his talks and I heard that his threats on killing people for stupid things aren’t just idle threats. He also introduced me to my new best friend in the JDK — JConsole. Now if I can get JDK6 installed, I could do some serious JConsole scripting . . .
Was this conference perfect? Nah . . Sunday got a little long, I think there was too many Groovy talks, the Men’s room was too small, and there weren’t nearly enough outlets for laptops. But I don’t regret going !
A Tale of String Equality
In Java there are many ways to check if a String object is equal to a constant string. Here are three I’m going to talk about:
str1=="Value"; str1.equals("Value"); "Value".equals(str1);
The first item is very problematic — it checks to see if str1 and “Value1″ are pointing to the same reference. In the language of C, we are checking to see if the pointers to these strings are pointing to the same space in memory. Since “Value” is a literal string, the chances of that happening are very small — especially if str1 was assigned from the user, a database, etc. This is the worst way to test string equality in Java. And, really, most of us should have learned that long ago.The second item is probably the most common and it works well enough, but it has disadvantages. The first one: what if str1 is null? If it’s null, then it has no “equals” method and you get an exception. So, really, the second item should be:
str1==null && str1.equals("Value")
Now a simple equality test becomes a compound statement, but it is still valid. But there is something more subtle happening here. The “equals” method accepts an object — any Object, in fact. So you give it a constant string as an plain Object, and in the method, it casts that Object into a String. So you are constructing on object out of a constant. Does that sound like a good idea? Not from from a performance perspective, it doesn’t. And you care about performance, right?The third item looks a little weird, yet you know that it’ valid Java-syntax. But there are rewards for doing it this way. First, that string constant won’t ever be null, so you don’t need a compound statement. And while “equals” accepts an Object, “str1″ is already an Object, so no re-creation needs to be done. But what if “str1″ is null? Why it catches that too! Because you can send “null” to the “equals” method and the result should always be “false”. It seems that our problems are solved!So, really, in spite of how it looks, the follow seems to be the best way to test for String equality:
"Value".equals(str1);

