Saturday, 22 August 2009

Unit testing code

I had to build a complex module this last week and hand it to another developer to integrate into the app. This reminded me of a usually unmentioned value of unit tests: documentation.

Unit tests are all about writing little test jackets of code that exercise the production code and make sure it works. At their best they are designed to test the output and scream it if is not right, though lots of tests just print out something for a human to examine and verify.

I usually write unit tests to verify my code anyway, so of course I delivered my test to the other developer so that she could see how to call my module. She could run the test, step through the code and explore how it works, and she could verify my assumptions about the inputs (the spec was vague) because she is getting the real inputs and I had to mock up mine for the test.

When I have to work with code I don't know I usually look for a unit test first to tell me how it works. Perhaps projects should consider putting less effort into documentation (which no one reads) and more into unit tests. Documentation drifts out of date. Unit tests either work or they don't and even the exercise of fixing them can be useful in finding out how things work. Better to keep them maintained than fix them on the fly though.

Tuesday, 11 August 2009

A new monitor

The new monitor arrived today from Dell. I expected it on Thursday but it turned up two days early. I won't complain.

It is an SX2210, a 21.5" (we still use inches to measure these things, how long before everyone switches to metric?) and it plugs into my laptop. The resolution is slightly lower than the laptop but not that I notice. I like to have a second monitor when I am working and this will do the job nicely.

It has a webcam built in and some connections for a sound box that Dell sells. I don't do video calls and I already have good speakers when I want to watch a DVD. It also has a load of USB connections, so I could use it as a USB hub, but I don't see that happening either. What I wanted was a damn good monitor with a crisp, clear image, and I got that. It says it does HD and there's an HDMI socket in the back. So I guess when I start using HD stuff this will work.

Its max resolution is 1920 x 1080. My laptop is 1920 x 1200 and my other monitor (24") is the same (there is a good reason for having two of them but let's not get boring). What happens to Linux when it changes monitors? Good things. It auto senses and snaps up the right resolution no sweat. I haven't seen Windows XP do that, maybe Vista or 7 does, anyway Linux definitely handles it nicely. The third monitor (3? Yes, long story, but they are all in regular use) is not a wide screen job and nothing flash. I don't recall the numbers for it but they are smaller. Anyway, under XP I always had to manually modify the settings, under Linux I do not.

Friday, 7 August 2009

Threadlocal

I ran into an interesting problem last week concerning Threadlocal. This is a class in Java. The details are here. You save something in a ThreadLocal class, usually held somewhere static, and any calls to fetch it out from the same thread will get the same value out again. You get the benefits of a static while staying thread safe.

This is really useful, but there are dangers, specifically there are problems with side effects. One of these I am about to describe.

Okay, we're about to commit using Hibernate. One of the fields in the Hibernate object maps to an object. Hibernate calls the object's method during the commit (I forget which method, probably serialize) and that method tries to get a configuration object from ThreadLocal. If it fails to get the configuration it instantiates one and carries on, loading the resulting configuration object into the ThreadLocal.

At this point bad things happen. That configuration object needs certain values and the default configuration does not do the job. We must have the configuration object loaded by something else and never by default.

This is an example of a side effect. Deliberate side effects can be good things. This one was not. It took a lot of time to figure out what was going on. We had no knowledge of the ThreadLocal. This was not our code, I won't embarrass the open source project it belongs to, but it would have been a lot better if an exception had been thrown if the configuration object was missing. We would have known what the problem was over a week ago.

So if you use ThreadLocals, or even statics, make sure you are really, really careful how they are initialised. You probably want to have them initialised in just one place using one mechanism.

Thursday, 6 August 2009

Thunderbird and Ubuntu

I run Thunderbird as my email client and some days it refuses to start.
I've found that reinstalling it and then rebooting helps, but not always.
Today I think I found the real reason is something do do with the dual monitor arrangement I have.
Usually there is a second monitor attached to my laptop. When the second monitor is missing but I have not changed the setting it screws up Thunderbird.

So a simple change of screen resolution (from 3840 x 1200 to 1920 x 1200 in my case) sorts it.
Now I can stop reinstalling and rebooting.

Glassfish plugin for Eclipse

I use Eclipse for Java development and usually the target application server is SJSAS, Sun's J2EE appserver. Sun seem to have trouble sorting out their naming of things sometimes. Recall Java version 1.5 or 5 or ??? It doesn't matter, but I think the story is that since they open sourced it they're calling it Glassfish. So, while my customer is calling it SJSAS I'm seeing Glassfish. This is fine.

At the moment the version we want is 2.1. There are preliminary versions of V3 available but not something I have time for just now.

What I do need is a better way to start and stop it and deploy the app for testing. They do this with a plugin in Eclipse which supports several app servers like JBoss etc. I tried various instructions I found on the web, people have gone to a lot of trouble on these. But the one that actually worked was here. The others involved downloading during the server setup and they gave me an ArrayOutOfBoundsException.

They basically use the Eclipse update mechanism to pull the plugin from
http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-1423.html
Then you can configure the server by using the server window, right click and pick 'New' and follow your nose.

However the update took a long time to install after it had pulled it down. I almost gave up waiting. It was sitting for ages taking about 50% of the CPU and looking a lot like an infinite loop from the outside. But it did finish eventually. I haven't verified all the functions but it definitely starts the server and stops it. I need to try out the deployment options.

Under JBoss my build just copies the ear to the deploy directory. That reloads automatically but if it doesn't (I don't always trust it) I can restart it from the plugin. I'm expecting to replicate that functionality for Glassfish but it won't be quite the same. I can copy to an autodeploy directory which ought to work but previous experiments seems to fail on this.

I will persevere.