« February 2007 | Main | September 2007 »

March 28, 2007

Vanilla Ice Was an Agile Visionary

Listen to this articleListen to this article

Once and for all could we all just get over pair programming as something novel and thus something about which to be suspicious and fearful. The idea that it's some new fandangled practice is utter bollocks! It's called COLLABORATION! and believe it or not, some of us have been pair-programming collaborating with much success for many years now and with no ill effects. You'd be amazed!

Getting people to collaborate takes more than simply mandating pair-programming. If you don't know how to do it, how about occasionally getting up off your bum and sitting with another developer. Perhaps once in a while you might like to try taking those goddam earphones out, turning around and asking for someone to come and watch what you're doing. Talk to other members of the team about your work. Involve other people in what you do. Fundamentally that's what pair programming is about. Yes, there are added benefits such as having your pair catch little mistakes here and there but more than anything it's the collaboration that comes from sitting with another human being and discussing what you're doing that makes the biggest difference.

Where I work now we all sit in close proximity, we all listen (whether we know it or not) to what everyone else is doing and all chime in if we believe (rightly or wrongly) we have something to contribute or even just to ask questions because something sounded interesting. Snobs, cowboys, incompetents and the socially-challenged are among those that might fear such behaviour; precisely the people we don't want on our project.

I highly recommend visiting Jason Yip's blog (among others) for ways in which you might get your team to collaborate more effectively and yes, pair-programming may well be one.

Leaking Locks

Listen to this articleListen to this article

Spoiler: JDK 1.5—and near as I can tell 1.6 even though it's supposed to be fixed—have a pretty fatal memory leak when using java.util.concurrent libraries.

How do I know?

Well, besides finding the earlier link via our good friends at Google, we recently switched from using the backport to the standard JDK libraries and the throughput of our application under load rapidly approached zero.

After spending some time creating a a quick-and-dirty load test on my own machine, I found I could easily replicate the problem with the added bonus of java.lang.OutOfMemoryErrors in under a minute. Running it under a profiler confirmed as much with the culprit being java.util.concurrent.locks.AbstractQueuedSynchronizer$Node.

"Never" cries the guy we work for. "Doug Lee's stuff has been around for a long time and I'll bet his stuff works and you guys have screwed something up!" he continues.

We all agreed and decided to replace the locking code in the class I'd just created (and presumably screwed up) with some good old-fashioned synchronisation.

Nope. The problem persists but it's not as bad this time. We clearly "fixed" something but not everything. Hmmm.

On further investigation we realised there was still some code in the call chain using the concurrent stuff so we decided, just for laughs, to revert back to using the concurrent stuff but use the backport libraries instead.

Voila! Suddenly the load test exhibited exactly the expected behaviour: no out-of-memory errors; no grinding to a halt; nice see-saw memory usage; and using only 2MB of heap instead of, well, as much as it could get (>64M in our case).

Stunned, we went back to the default JDK version. Yup! Problem is back and not just in our own locking code either, we noticed the problem in much of the concurrent classes including the collection implementations.

The good news is that using backport we now have a build that works.

The scary part is that I can only presume some Sun engineer decided he knew better and screwed the pooch right royally on this one.

March 22, 2007

Learn to Say "No!"

Listen to this articleListen to this article

I can take it no longer. If I hear or read about how Getting Things Done (GTD) saved yet another person's "life" I'm going to scream. This fascination the world (and geeks in particular) have with doing more and more stuff is frightening.

When you feel there is just so much to do in your life that you can't seem to make it through the day without stressing about something, that your life is spiralling out of control and there seems to be nothing you can do about it, there is an alternative course of action: DLS - Do Less Stuff™

Yes, hard to believe but there is actually no particular need to devise yet more processes in order to deal with the stuff that is ultimately controlling you. Instead, you can actually take control of your life and say "I'm going to do less stuff" and tell those that would foist their agendas upon you to go jam it.

I choose not to reduce my life (and the enjoyment thereof) to a series of prioritised index cards pinned to a wall.

March 17, 2007

Continuous Integration for Rails Just Got A Whole Lot Easier

Listen to this articleListen to this article

If you already have a continuous integration (ie build) server (such as Pulse, Bamboo, Hudson, or even the venerable old CruiseControl) and you've been trying to include some of your Rails applications then your life just got a whole lot easier.

Enter CI::Reporter. To quote the documentation:

...an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant‘s JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.

So, I simply installed the gem on the build-server and the plugin into my plugins project, configured the build to slurp up the generated XML files and voila! I now get build notifications letting me know how many tests passed and which ones failed.

Thanks Nick!

March 15, 2007

Installing RedHill on Rails Plugins via HTTP

Listen to this articleListen to this article

After much installation pain and anguish experienced by some users of our plugins (due mostly to outages with RubyForge SVN servers and the inability of some users to access SVN from behind firewalls), I've finally managed to spend some time getting a plugin installer-friendly HTTP mirror up and running.

The root of the mirror can be found at http://www.redhillonrails.org/svn from which you can browse the entire repository.

If you live on the edge, you'll find them at http://www.redhillonrails.org/svn/trunk/vendor/plugins.

If you're after are the Rails 1.2 stable compatible plugins, you'll find them at http://www.redhillonrails.org/svn/branches/stable-1.2/vendor/plugins.

If you're after the older Rails 1.1.6 versions, they're available at http://www.redhillonrails.org/svn/tags/release-1.1.6/vendor/plugins.

The mirror is presently refreshed once a day which should be enough for most people.

As always, let me know if I've right royally screwed something up. I've manually tested all of the above but "it works on my machine" definitely applies in the case I'm sure.

March 13, 2007

Bug Reporting 101

Listen to this articleListen to this article

So, you found what you think is a bug in a bit of software and you need it fixed desperately, so desperately that you take advantage of the fact that you have direct contact with the developer(s) and ask for help. Allow me to give you some handy hints as to what kind of information may be useful to said developer(s) when diagnosing a problem experienced intermittently by your lone yak herder in outer-Mongolia:

  • Have you done a quick search on Google? If not, go to jail; do not pass go; do not collect 200 dollars
  • What version of the software are you using?
  • What are the steps necessary to re-create the problem?
  • Is there a stacktrace?
  • Have you changed anything recently? And I mean ANYTHING? You don't get to decide if it's important enough to warrant a mention
  • What other software/add-ons are you running at the same time?
  • Which operating system/s and what version/s are you using?
  • Is there a database involved? If so, what platform is it running on and what version are you using?
  • Does this happen locally or only when run remotely?
  • Does it happen in development/test/production/etc?
  • ...

In fact, the more information you provide the quicker the problem (if in fact there even is one) is likely to be solved because quite frankly, and perhaps contrary to popular belief, not only does "You're software sucks and we might stop using it if you don't fix it" not really carry that much currency, it doesn't really help much either.

Update: As fate would have it, comments seem to be barfing. Feel free to send me your comments via email and I'll add them manually until the problem is resolved.

March 05, 2007

Monitoring Java Processes under Mac OS X

Listen to this articleListen to this article

Update: After a bit of googling I discovered that it's a bug which is fixed in Java 6 (Mustang) and relates to, wait for it, user names containing an underscore. Go figure!

So today, after I don't know how many years of doing Java development, I find out there is a command to list all the running Java processes. It's available on all platforms I could find and it's called jps. On most platforms it'll display something like:

1170 Jps -lm
1162 org.apache.tools.ant.launch.Launcher -cp  dist

Except under Mac OS X where you'll get something more like:

1170 Jps -lm
1162 -- process information unavailable

Pretty bloody useless!

So, I wrote a little ruby script to simulate the desired behaviour as much as possible (by using the built-in jps to collect the process ids; then filtering the output from ps accordingly):

#!/usr/bin/env ruby

require 'set'

pids = Set.new

`#{ENV['JAVA_HOME']}/bin/jps`.each_line do |line|
  pids.add($1) if line =~ /^(\d+) /
end

`ps -x -w -w -o pid,command`.each_line do |line|
  print line if line =~ /^ *(\d+) / && pids.include?($1)
end

Which, when run, produces output similar to (line continuation not included):

1162 /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/java \
  -classpath /opt/local/share/java/apache-ant/lib/ant-launcher.jar \
  -Dant.home=/opt/local/share/java/apache-ant \
  -Dant.library.dir=/opt/local/share/java/apache-ant/lib \
  org.apache.tools.ant.launch.Launcher -cp  dist

Granted it does produce lots more output than standard jps but it does at least produce something useful to look at when monitoring Java processes. Best of all, it means we can automate the monitoring in a manner that works across most platforms.

If anyone has a Better Way™, I'm all ears.