CruiseControl.NET 1.1 Released

CruiseControl.NET 1.1 was released this week. I’ve been taking a bit of a back seat on the project in recent months, but it’s been good to see a number of other people stepping up and getting involved, plus of course Owen Rogers continues to provide project leadership.

Check here for release notes.

As an aside – CCNet has moved to using Google Groups for mailing lists in light of the recent Sourceforge / GMail problems. Check here for more details.

The power of a fast build

When I build the project I currently work on, I smile every time I see the last 2 lines:

BUILD SUCCEEDED

Total time: 9.5 seconds.

And before you start doubting, yes we do have a pretty comprehensive test suite! So comprehensive in fact that I’m quite happy making medium – large size refactorings rapidly. In fact, in the space of just over an hour I’ve been able to check in 4 such changes.

The secret to this? No out-of-process communication. All of these tests run within the code. The application communicates with a message bus and we test the actual message objects produced by the application and generate the actual messages consumed by the application, but we never actually hit the network thanks to some appropriate stubbing of the middleware vendor’s Transport API.

The only problem? At some point in the future I’ll end up on a project again with a 15+ minute build and I’ll be pulling my hair out…

Team City vs. CruiseControl.NET

I’m a big fan of JetBrains. Their IntelliJ IDEA Java IDE, which I first used 5 years ago, I think was the biggest step forward in code-editting productivity since the Smalltalk browser, and they continue to innovate on this idea while adding similar products in the .NET world with ReSharper.

Last year I was talking to a couple of the guys from JetBrains and they mentioned they were working on a Build Server product. That has now materialized in the form of TeamCity. You don’t need to look at the TeamCity web page for very long before realising that it’s JetBrains’ own version of CruiseControl or CruiseControl.NET. In fact they even compare against these projects here.

Clearly the comparison is a little biased (there’s only 1 feature in CCNet’s Web UI that they actually include in their list for example) but I’m probably biased in saying that. 🙂

There’s a lot of lessons I’ve learned along the way being one of the CCNet project leads, the biggest being that a huge chunk of our time and effort is spent purely on integrating with all the different source control tools we talk to (14 at the last count) and that’s with a fairly limited Source Control interface and no UI configuration. The only reason we’ve been able to do this is through community involvement in the project and I’ll be interested to see if Jetbrains introduce a fairly open API for plugging in custom sourcecontrol bridges.

I think one of the other key benefits to CCNet is how customisable it is through plugins generically, along a number of axes. The Web Dashboard for example can be customised through adding your own XSL stylesheets or actually adding your own code-implemented plugins. The build server does similarly. If Jetbrains can get this customisation part right, I think both CruiseControl and CruiseControl.NET will see their user bases shrink dramatically.

Which will leave me to work on all those other open source projects I’m interested in. 🙂

Careful with those member variables, Eugene

OOP (Object oriented programming,) or just OO, is a wonderful way of programming. I’m quite happy to say that since I’ll be honest and say I didn’t really get it properly until 2 or 3 years ago. Sure, I’ve been programming with Java and C# since 1998, but that doesn’t really mean I was doing OO all that time. A lot of people use Java or C# to write ‘object procedural’ or ‘class oriented’ programming. If you understand OO, you probably know already what I’m talking about, and if you don’t…. well I’ll try and explain.

There are a few pointers that code has not been written in the spirit of OO, and I’m going to talk about just one such small smell here. This smell is what I like to call ‘member variable madness’.

OO is to a large extent about encapsulating state. The state in OO is held in the member fields of objects. Those fields may be encapsulated data, or references to other objects. Member fields are used so that the object can keep track of data, or references, between calls to its public methods. Member fields consist of member constants (readonly in C# and final in Java) and member variables (i.e. not a constant.) Member constants are used when a piece of member data is immutable, or when a reference is a constructor-initialised dependency on another object.

Member variables are not meant to be a temporary scratchpad between public and private methods. This is not state that exists between externally stimulated method calls. What’s bad about using member variables as an internal scratchpad? I think there are at least a couple of reasons:

  • Clarity. When I look at a class for the first time, I look at its member fields. This tells me what the object is encapsulating as part of the whole program. If there are a bunch of scratchpad variables here that confuses this concept.
  • Correctness. Everytime you introduce a new member variable to a class, you are introducing another ‘degree of freedom’ of all the objects of that class. This means to be sure you haven’t broken anything you have more testing to do. Correctness can be broken in at least 2 ways:
    • Thread safety / interference. If you have 2 concurrent threads accessing one object, they will share the member variables of that object. There is a big chance they could interfere with each other leading to hard-to-find bugs
    • Initial value. If you use local variables, you know you need to initialise it every time you define it (otherwise the compiler will complain). However, with a member variable you need to only initialise it once, somewhere in the class. How do other usages know it has been initialised? Do they need to re-initialise? Might that actually break the required behaviour?

Thankfully, this smell is an easy one to fix. Simply replace the member variable with a local variable in the scope where it is initialised, then pass the variable as an argument to any other methods that require it. You may find that you now have methods with long parameter lists, but this may suggest that you need to introduce new classes to encapsulate such groups of variables anyway.

If you’re interested more in this area I recommend Ivan Moore’s ‘Programming in the Small’ series on his blog . Pair-programming with Ivan taught me more about OO programming than any other time in my career.

Sun X4500 – Taking the phrase 'disk space is cheap' to the next level

I love it when big old-school technology companies do something that surprises me. Sun’s new X4500 server does just that. It takes 48 (yes, 48) standard hard disks and puts them in a 4U server. With the 500GB hard disks available today that’s 24 terabytes in one server. That’s a frak load of disk space. To put it another way, in a 48 U rack (and the mother of all air conditioning units) that’s … umm my head can’t cope … 288 TB … What comes after ‘Terra’? When 1TB disks come out later this year, 1 rack will be over half way there.

Oh, its got 2 dual-core CPUs and (I love this bit too – very old school!) 4 gigabit ethernet ports. Reminds me of the old happy-meal cards (anyone get that?)

So what do you do with that amount of storage in just 1 server? Well apart from hosting the world’s most impressive mp3 collection, I can think of a few things:

  1. Data Warehousing gets darn cheap. Lets all start doing it! Lets never actually delete anything, just archive it to a different table. If its good enough for GMail, it should be good enough for our apps.
  2. Put your source control server on it, and check your continuous integration builds into revision control, and never have to worry about filling up the disk. Actually, scratch that one, I forgot about weblogic.jar being 17.5 GB by itself… Seriously though, this would make a great cross-department source control beast that would last for years.
  3. Give everyone huge shared and personal networked folders to work with. Turn off the quotas!
  4. Any application which is data heavy but CPU light and has separate application and database tiers could use this machine to host both tiers – no network traffic!

I’m interested to see what people do actually use it for. Such big advances can lead to interesting possibilities.

3 shells of Agile

As an agile software consultant, I’ve now been involved with quite a few clients who are either trying out, or transitioning to, agile methods to deliver software within their organization. Some of the following types of questions are frequently raised:

Do we have to be completely agile for it to work at all?

How do we start being agile?

How do we work with parts of the organization that aren’t agile?

The organization already has a strict programme management methodology – how does agile work in that environment?

In trying to answer these questions, I think it can be helpful to think of agile software development to be made of 3 shells:

Agile Shells

What this diagram shows is that we can think of breaking up all the different agile practices into 3 groups:

Agile Programming includes the development practices typically found in eXtreme Programming: evolutionary design, continuous integration, test-driven development, pair programming, domain-driven design.

Agile Projects / teams includes the agile project management and whole-team practices: short iterations, planning games, daily status meetings, information radioators, retrospectives, on-site customer proxy, acceptance-test driven requirements.

Agile Programs / organizations is referring to what happens when an agile project acts in an agile way with the bigger environment: frequent delivery to production hardware, on-site customer, frequent stake-holder meetings, agile support (e.g. from the IT operations dept.)

What I think is important is that there is strong requirement relationship looking inward, but a weaker requirement relationship looking outward. For example, if a whole program of work is going to be agile, its internal teams can’t be acting like mini waterfall projects. Similarly, the programmers on a 4 person team might well be able to practice agile programming techniques even if they don’t have an iterative development cycle.

I think breaking up agile in this way helps to answer the type of question we started out with. Some organizations might want to start with some of the more inward practices before pushing them further out. A classic example of this might be not being able to get a real on-site customer (an agile organization thing to do) but making do just with a customer proxy (which is what you’d have if you were trying to have an agile team.) Similarly, people might be willing for the team to deliver internally every iteration (maybe to UAT) but just aren’t setup to deliver to production more than once every 2 or 3 months.

Breaking up the practices in this way also helps you focus what you want to do first – it’s important to realise you might not need to be ‘completely agile‘ in one shell to support the next one out. As a first start to using agile, you might try having stake-holder meetings as part of an agile organization every iteration; have 2-week sprints, planning games, and daily status meetings as an agile team; and kick-off some technical practices like continuous integration to start out with. After a couple of iterations you’d probably find you’d need to add some more technical practices to support your iterations, and that you might need a designated customer proxy to better support the stake-holder community.

The final point to consider is how an agile project can work in the context of non-agile environmental constraints – this issue comes up frequently when introducing agile into businesses with large, dedicated IT organizations and management structures. By defining what we mean by an agile team or project, we are better able to define a strong interface between the agile team and the rest of the IT organisation. The team might need to produce relevant documentation, they might need to provide upfront requirements to other non-agile development teams. But the point is if they can’t work as part of an agile organization they can still look introspectively and find how they want to work as a team, and what technical practices they want to follow.

In closing, expecting an organization to become agile overnight is obviously unrealistic. A little analysis of breaking up the agile practices into broad areas can help transition an organization in a more controlled way.

Buildix – a complete SCM strategy in a free box

Buildix is a Linux distribution with a bundled source control server, issue tracker and continuous integration. In short, its a complete development server in a box, which requires almost no configuration. Even better its completely free since it uses only open-source software. And even better than that there’s a free VMWare virtual appliance (which will work with the free VMWare Server) so you can try it out with almost zero barrier to entry (apart from the download time and about half an hour to try it out.)

I’m really glad ThoughtWorks have made this available to the public – huge kudos to Chris Read, Julian Simpson and Tom Sulston for making this happen. I actually saw Buildix used on its first couple of projects before it went public and was very impressed.

Now I just need to help them get CruiseControl.NET running on it under Mono. 🙂

Update – Chris Read (one of the buildix developers) blogs more about how it came about

A peace-sign

I’m British, working in America, for a German company, and part of my team is in Russia. I reckon if I told someone 20 years ago that this might happen in 20 year’s time, I’d probably have been thrown in a loony bin.

Or as one of my Russian co-workers put it, I’m a victim of globalisation. 🙂

Finally I get to use C# 2 closures

For the last couple of months I’ve been using .NET 2 for the first time. There are a bunch of great new language features in there, generics being the most obvious (and implemented properly in .NET rather than the hack in Java), but another biggy is anonymous delegates.

One use of anonymous delegates is just to inline methods, e.g.:

public void MyFunkyExample()
{
Timer timer = new Timer();
timer.Elapsed += DoSomething;
timer.Interval = 1000;
timer.Start();
}

private void DoSomething(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello World! (at {0})", e.SignalTime);
}

becomes:

public void MyFunkyExample()
{
Timer timer = new Timer();
timer.Elapsed += delegate (object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello World! (at {0})", e.SignalTime);
};
timer.Interval = 1000;
timer.Start();
}

This is handy occasionally when you have a 1 or 2 line method that only gets used as a delegate.

However, the real power of anonymous delegates comes when using them as closures. Take the following code as an example:

public void MyFunkyClosureExample()
{
string[] names = new string[] { "Fred", "Bob", "Sue" };
foreach (string name in names)
{
SetupTimer(name);
}
}

private void SetupTimer(string name)
{
NamedWriter writer = new NamedWriter(name);
Timer timer = new Timer();
timer.Elapsed += writer.Write;
timer.Interval = 1000;
timer.Start();
}

private class NamedWriter
{
private readonly string name;

public NamedWriter(string name)
{
this.name = name;
}

public void Write(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello {0}! (at {1})", name, e.SignalTime);
}
}

Now we want to have several timers, but the event of each has different behaviour depending on some local value when the timer event is bound. Pre C# 2.0 you have to setup a custom class to handle this, but compare with the anonymous delegate version:

public void MyFunkyClosureExample()
{
string[] names = new string[] { "Fred", "Bob", "Sue" };
foreach (string name in names)
{
SetupTimer(name);
}
}

private void SetupTimer(string name)
{
Timer timer = new Timer();
timer.Elapsed += delegate(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello {0}! (at {1})", name, e.SignalTime);
};
timer.Interval = 1000;
timer.Start();
}

This is much cleaner since we don’t need to introduce that custom class.

Using closures can get a little hairy, especially when you’re trying to figure out which value of variables actually get bound – check out one of Jeremy Stell-Smith’s recent entries on the subject. But of course, you’ll have plenty of automated tests to check what you’re doing, right? 😉

PS – apologies for the lack of decent formatting – I’m still getting to grips with WordPress.

Picasa Web – Now I'm glad I didn't bother with Flickr

For a while now I’ve been a little envious of people using Flickr to have fancy photo galleries online. I’ve almost used it a couple of times, but for me the whole idea of using a web site to manage pictures just didn’t work. I’ve used Picasa as my photo library and I wasn’t prepared to move away from a desktop-based client to handle my (more than 1GB worth of) digital photos.

When I bought my Mac Mini I was hoping iPhoto might be amazing, and I was considering using it and .Mac to host photos. iPhoto just didn’t work for me either, and I kept using Picasa, and my Photo Blogger Blog (which Picasa integrates fairly nicely with) to publish the odd photo now and then.

But a Photo Blog isn’t the same as an online photo album, and what I really wanted was for Google to add online features to Picasa so that I could manage a web photo library from a desktop client.

Someone at Google must have been listening, since they’ve done just this, and its free. The first 250MB costs zilch, and if you want more its $25 / year for 6GB of storage. That means I can have my entire, full resolution, photo library online, share subsets of it with the world, and yet still have a local client for editting, viewing offline, etc. Flickr, your time is up [1].

My online Picasa gallery is at http://picasaweb.google.com/mike.b.roberts and this replaces my Photo Blog.

[1] OK, Mac-weenies will still use Flickr because Picasa doesn’t have a Mac client yet. But you can still upload/manage photos using the Picasa web interface, and I doubt it will be that long before a Mac-Picasa is released.