a little madness

A man needs a little madness, or else he never dares cut the rope and be free. -Nikos Kazantzakis

Zutubi

First impressions of StAX

I have recently been working on this issue, converting some of Pulses‘ XML processing from using DOM to using StAX. Whilst the DOM API is a simpler to work with, it is not so memory friendly and was becoming a problem for some of our customers.

I chose to try StAX rather than SAX because it was developed to be a middle ground between DOM and SAX, having the memory efficiency of a streaming parser like SAX whilst retaining a simpler API like DOM.

A quick note: This is not an exhaustive analysis of the pros and cons of the various XML APIs as this has been done before. Rather, this is a comparison of some of the things I made a mental note of whilst doing the conversion.

DOM

  • Works with an in memory tree representation of the XML document, and therefore has high memory requirements for large documents
  • Easy to use API that allows you to navigate the XML document in whatever way is most appropriate to. You can process a element as often as you like, go forwards and backwards as well as search through the document.

This is what our code looked like before the conversion.

protected void processSuites (Element root)
{

    String suiteElement = getConfig().getSuiteElement();

    Elements suiteElements = root.getChildElements(suiteElement);
    for(int i = 0; i < suiteElements.size(); i++)
    {
        processSuite(suiteElements.get(i), tests);
    }
}

Note that using dom is simply manipulating an in memory tree.

SAX

  • Implementations manage the state in the form of instance variables. This works well for simple documents, but becomes more difficult to manage as the document gets more complex.
  • Processing of an element typically occurs when you encounter the elements end tag, as only then is all of the elements content available. Until you reach an end tag, you have no real idea of how far through an element you are.
  • You only need to respond to elements that are of interest. Ie, when you receive a callback for one of these elements, just do nothing and return.

StAX

  • Implementations typically manage the state on the execution stack, with a new method call for each element that is encountered. This makes the code pretty easy to read as it is self documenting.
  • You need to process each and every (unfiltered) tag and event in the xml document. This is rather low level, and without care can lead to confusion and complications.

And this is what the code looked like after the conversion:

protected void processSuites (XMLStreamReader reader) throws XMLStreamException
{

    expectStartElement(ELEMENT_SUITES, reader);
    reader.nextTag();

    while (reader.isStartElement())
    {
        if (isElement(getConfig().getSuiteElement(), reader))
        {
            processSuite(reader);
        }
        else
        {
            // ignore this element.
            nextElement(reader);
        }
    }
    expectEndElement(ELEMENT_SUITES, reader);
}

My use of StAX is a little more regimented. I begin and end each method with an assertion that I am at the element I expect to be (this has the advantage of documenting the implementation). The rest of the implementation is similar to its DOM counterpart, expect that rather than simply asking for the elements I want to process, I need to loop over all the elements, skipping over those that are not of interest.

Summary

Overall, I am happy with the way the conversion has turned out. A couple of things were unexpected. The StAX API did not include any higher level utility functions that allowed you to move around at the element level, only between the end tag of one element and the start tag of the next. The other was that it required a fair amount of effort to write the code such that it was resilient to unexpected data in the reports. Every tag has to be processed after all.

CITCON Paris 2009: Mocks, CI Servers and Acceptance Testing

Following up on my previous post about CITCON Paris, I thought I’d post a few points about each of the other sessions I attended.

Mock Objects

I went along to this session as a chance to hear about mock objects from the perspective of someone involved in their development, Steve Freeman. If you’ve read my Four Simple Rules for Mocking, you’ll know I’m not too keen on setting expectations, or even on verification. I mainly use mocking libraries for stubbing. Martin Fowler’s article Mocks Aren’t Stubs had make me think that Steve would hold the opposite view:

The classical TDD style is to use real objects if possible and a double if it’s awkward to use the real thing. So a classical TDDer would use a real warehouse and a double for the mail service. The kind of double doesn’t really matter that much.

A mockist TDD practitioner, however, will always use a mock for any object with interesting behavior. In this case for both the warehouse and the mail service.

So my biggest takeaway from this topic was that Steve’s view was more balanced and pragmatic than Fowler’s quote suggests. At a high level he explained well how his approach to design and implementation leads to the use of expectations in his tests. I still have my reservations, but was convinced that I should at least take a look at Steve’s new book (which is free online, so I can try a chapter or two before opting for a dead tree version).

A few more concrete pointers can be found in the session notes. A key one for me is to not mock what you don’t own, but to define your own interfaces for interacting with external systems (and then mock those interfaces).

The Future of CI Servers

I wasn’t too keen on this topic, but since it is my business, I felt compelled. I actually proposed a similar topic at my first CITCON back in Sydney and found it a disappointing session then, so my expectations were low. Apart from the less interesting probing of features on the market already, conversation did wander onto the more interesting challenge of scaling development teams.

The agile movement recognises the two main challenges (and opportunities) in software development are people and change. So it was interesting to hear this recast as wanting to return to our “hacker roots” — where we could code away in a room without the challenges of communication, integration and so on. Ideas such as using information radiators to bring a “small team” feel to large and/or distributed teams were mentioned. A less tangible thought was some kind of frequent but subtle feedback of potential integration issues. Most of the time you could code away happily, but in the background your tools would be constantly keeping an eye out for potential problems. What I like about this is the subtlety angle: given the benefits it’s easy to think that more feedback is always better, without thinking of the cost (e.g. interruption of flow).

Acceptance Testing

This year it seemed like every other session involved acceptance testing somehow. Not terribly surprising I guess since it is a very challenging area both technically and culturally. As I missed most of these sessions, they are probably better captured by other posts:

One idea I would call attention to is growing a custom, targeted solution for your project. I believe it was Steve Freeman that drew attention to an example in the Eclipse MyFoundation Portal project. If you drill down you can see use cases represented in a custom swim lane layout.

Water Cooler Discussions

Of course a great aspect of the conference is the random discussions you fall into with other attendees. One particular discussion (with JtF) has given me a much-needed kick up the backside. We were talking about the problems with trying to use acceptance tests to make up for a lack of unit testing. This is a tempting approach on projects that don’t have a testable design and infrastructure in place — it’s just easier to start throwing tests on top of your external UI.

Even though I knew all the drawbacks of this approach, I had to confess that this is essentially what has happened with the JavaScript code in Pulse. We started adding AJAX to the Pulse UI in bits and pieces without putting the infrastructure in place to test this code in isolation. Fast forward to today and we have a considerable amount of JavaScript code which is primarily tested via Selenium. So we’re now going to get serious about unit testing this code, which will simultaneously improve our coverage and reduce our build times.

Conclusion

To wrap up, after returning from Paris I plan to:

  1. Give expectations a fair hearing, by reading Steve’s book.
  2. Look for ways to improve our own information radiators to help connect Zutubi Sydney and London.
  3. Get serious about unit testing our JavaScript code.
  4. Get PJ and JtF to swap the dates for CITCON Asia/Pacific and Europe next year so I can get to both instead of neither! ;)

If I succeed at 4 (sadly not likely!) then I’ll certainly be back next year!

CITCON Paris 2009

As mentioned Daniel and I both attended CITCON Paris the weekend before last. I’ve not had a chance to post a follow up yet as we also took the opportunity to eat the legs off every duck in France (well, we tried).

Firstly a huge thanks to PJ, Jeff, Eric and all the other volunteers for another great conference. Thanks again to Eric and Guillaume for acting as local guides on Saturday night. As always, the open spaces format and mix of attendees delivered a great day. It was also great to see a few familiar faces from the year before in Amsterdam (and a familiar shirt thanks to Ivan :) ).

This year I proposed and facilitated a single topic: Distributed SCM in the Corporate World. I finally added a full write-up on the conference wiki earlier in the week for those who are interested. For the impatient, here are my take-aways from the session:

  1. Of the distributed SCMs, there is not much traction in the corporate world just yet, although git appears to have gained a foothold. (Obviously our sample size is small, but I also expect CITCON attendees to be closer to the edge than the average team.)
  2. Where distributed SCMs are used, the topology is still like the centralised model. However, the ability to easily clone and move changes between repositories presents opportunities to work around issues like painful networks (contrast this to special proxy servers which are needed in similar scenarios with centralised SCMs).
  3. The people using git liked it primarily for its more flexible workflow and better merging. It’s conceivable to have this in the centralised model too, but no single centralised contender was mentioned.
  4. So far the use of distributed SCMs didn’t seem to have practical implications for CI – probably due to the use of a centralised topology.

Looks like we’re still waiting to see more creative use of distributed SCMs in corporate projects – perhaps it is something worth revisiting in future conferences. I hope to post on some of the other sessions I attended at a later date.

Zutubi @ CITCON Paris 2009

Any excuse is good enough to get me to Paris, especially while it is only a train ride away. Daniel has actually been tempted all the way from Sydney!1 So you’ll find us both at CITCON Europe 2009 tomorrow night and Saturday. We’re both looking forward to a great weekend, after nothing but positive experiences at previous events. Hopefully we’ll even get a few questions about the new Pulse 2.1 Beta while we’re there!


1 Although combining it with a well-deserved holiday may have been a factor…

Software As Engineering

Bertrand Meyer (of Eiffel fame) posted recently on The one sure way to advance software engineering. Meyer’s thesis is that by thorough examination of past software failures, we could learn from those mistakes. This is true enough, but then Meyer goes on to suggest that we:

… pass a law that requires extensive professional analysis of any large software failure. … The law would have to define what constitutes a “large” failure; for example it could be any failure that may be software-related and has resulted in loss either of human life or of property beyond a certain threshold, say $50 million.

Leaving the issue of making this law aside, the fact that this would only apply to such “large” failures necessarily marginalises the utility of the analysis. The truth is that such projects are a small minority of overall software development. Lessons learned from projects where such a large failure is a possibility – particularly where safety is involved – may not apply to the vast majority of software development. This doesn’t make the suggestion useless, but it makes it unlikely to have a significant impact on software engineering as a whole.

Meyer’s post also triggered a resurgence of the age-old debate of whether software development is worthy of the “engineering” label. With bugs so prevalent in mainstream software, people (mostly developers themselves) question the professionalism of our industry. This reminds of the EclipseCon 2007 keynote by Robert Lefkowitz, which draws attention to the EULA used by Microsoft. In particular, Lefkowitz asks why Microsoft1 should be allowed to disclaim all warranty and liability for damages incurred by the use of their software. Why doesn’t the law protect the market from buggy software?

The answer is simple: we aren’t all Larry Ellison, and cost does matter to the rest of us. The market might wish for higher-quality software, but to make this law would lead directly to a huge increase in the cost of software development. Consider the canonical example of software that is made to the highest standard: the code that controls space shuttles. The linked article quotes a figure of $35 million per year to develop and maintain 420,000 lines of code2. Consider that Microsoft Windows is about two orders of magnitude larger than this, and that the complexity of a code base grows faster than linearly with respect to the number of lines of code. The cost of bringing Windows up to shuttle-quality is unbearable, even for an 800-pound gorilla.

Does the fact that we need to trade off quality versus cost mean that development should not be considered as engineering? On the contrary, I believe that making sensible trade-offs is one of the very things that defines engineering. Engineering operates in the real world of scarce resources and budget constraints, and great engineers how to strike the right balance. They can also do more with less, by caring about their work and always seeking efficiency. I’ve met and worked with many developers that exhibit these traits, so I believe that there is hope for us yet.


1 I presume as a proxy for the whole industry.
2 Lines of code may be a weak metric, but I don’t think it detracts from the main point.

Stack Overflow: Classic Metric Abuse

It had to happen sooner or later, but when a Stack Overflow user posted tips to gain reputation fast, the proverbial hit the fan. Why? Go ahead and read the 6 Simple Tips, which describe how to change your contribution behaviour to optimise for reputation. Notice how none of these tips are concerned with improving the quality of your contributions. In fact, some of them actively encourage sacrificing quality in favour of gaining points:

1. Be the First to Answer. Even at the cost of quality.

In Stackoverflow answers are arranged first by vote number and submission/edit time. Being the first answer that people see is a huge advantage.

This is a perfect illustration of metric abuse in action. By using the reputation “magic number” as an incentive, Stack Overflow encourages users to optimise for reputation rather than quality. Amusingly, Joel himself posted on this very topic some years ago:

“Thank you for calling Amazon.com, may I help you?” Then — Click! You’re cut off. That’s annoying. You just waited 10 minutes to get through to a human and you mysteriously got disconnected right away.

Or is it mysterious? According to Mike Daisey, Amazon rated their customer service representatives based on the number of calls taken per hour. The best way to get your performance rating up was to hang up on customers, thus increasing the number of calls you can take every hour.

Perhaps Joel should have a word to Jeff. I suspect that the response will be to tune the reputation system to plug these holes. If that is indeed the response, I’d like to ask Jeff: Have You Met Your Dog, Patches?

Pulse Continuous Integration Server 2.1 Beta!

Exciting news: today we’ve pushed the latest version of Pulse, namely 2.1, to beta! This is the culmination of months of hard work on a ton of new features and improvements, including:

  • Project dependency support.
  • Easier multi-command projects.
  • Personal build improvements.
  • Fine-grained cleanup rules.
  • Built-in reference documentation.
  • Pluggable commands (build tool support).
  • A simpler, faster configuration UI.

The new features are described in more detail on the 2.1 beta page. The largest are the first two: dependencies and multi-command projects.

Project Dependencies

The ability to deliver artifacts from one build to another is a long-standing feature request. Pulse 2.1 supports this as part of a larger dependencies feature. Essentially you can declare one project to be dependent on another, allowing the downstream project to use artifacts built by the upstream one. Artifacts are delivered through an internal artifact repository.

The dependencies feature goes beyond artifact delivery. It also includes smarter triggering for dependent projects, the ability to rebuild a full dependency tree and a new “dependencies” tab which allows you to visualise the dependency graph.

Dependency support is built on top of Apache Ivy. Our aim is for interoperability with existing tools like Ivy and Maven, but without being Java-specific.

Multi-Command Projects

We’ve always had support for multi-command projects in the Pulse build core. However, to access this full flexibility you previously had to write an XML “pulse file” by hand. As of 2.1, the configuration GUI exposes the full flexibility of the underlying build core. This allows you to define multiple recipes per-project, each of which can have multiple commands. All of the advanced command options once restricted to XML files are now also accessible in the GUI.

A key feature related to this is the ability to plug in new commands (e.g. to support a new build tool), and have the plugin seamlessly integrated into the add project wizard. If you plug in support for a command, you get simplified wizard creation of single-command projects using your plugin for free.

Give It A Go!

You can download Pulse today to try it out. Free licenses are available for evaluation, open source projects and small teams.

Functional vs “Java” Style

Stephan Schmidt started it with his third point:

Do not use loops for list operations. Learning from functional languages, looping isn’t the best way to work on collections. Suppose we want to filter a list of persons to those who can drink beer. The loop versions looks like:

List<Person> beerDrinkers = new ArrayList<Person>();
for (Person p: persons) {
    if (p.getAge() > 16) {
            beerDrinkers.add(p);
    }
}

This can – even in Java – be rewritten to a more a functional programming style. For example using Google collections filter:

Predicate<HasAge> canDrinkBeer = new Predicate<HasAge>() {
    public boolean apply(HasAge hasAge) {
        return hasAge.getAge() > 16;
    }
};
List<Person> beerDrinkers = filter(persons, canDrinkBeer);

Then Cedric Beust countered with:

No loops

Java is not very well suited to a functional style, so I think the first example is more readable than the second one that uses Predicates. I’m guessing most Java programmers would agree, even those that are comfortable with comprehensions and closures and especially those that aren’t.

I guess this means I’m not “most Java programmers”. Although I find the verbosity of the anonymous Predicate in Stephan’s code lamentable, aside from that I think the functional style is far superior. And I don’t believe it should be seen as in any way at odds with “normal” Java style. There’s no magic here: it’s just a straightforward anonymous class and filtering is a very simple concept to understand. Conceptually it is no harder than the explicit loop: in fact it is easier as you know the higher purpose as soon as you see “filter”.

The higher level of abstraction is the key to its superiority. Every non-trivial Java project will include many instances of searching, filtering, folding and so on of collections. Repeating this most basic of logic time after time fills the code with mechanical details that hide its true purpose. Why not get those details right once (in a library) and then never have to see them again?

In fact, once you embrace this style, things get even better. Not only can you reuse basic operations like filtering, you can also:

  1. Compose these operations to form even higher-level manipulations.
  2. Build up a reusable set of functors (Predicates, Transforms, etc) instead of using anonymous classes.

The latter point is important, as it allows you to remove an even more damaging sort of repetition — that of your project’s domain-specific logic. Reduce Stephan’s example to:

List<Person> beerDrinkers = filter(persons, new CanDrinkBeerPredicate());

and it is clearly superior.

Really, I think it is a shame to see Java programmers hesitant to use this style. The ideas may come from the functional world, but there is nothing but basic Java code at work here. The abstractions are both simple and powerful, which to me is the very definition of elegance.

Apple and the Futurist

I know what you’re thinking: yet another blog about the current App Store controversy. Perhaps you’re wondering which I’ll take out of the disenchanted iPhone developer / one-eyed fanboy angles? Well, for a change, neither. I’d actually like to start with a story…

Some years ago, when my wife and I were buying our first apartment, I found myself making small talk with the present owner. Following the usual script, I inquired how the chap made his living — and discovered that he was a futurist. I took this to mean he was some sort of Dr Who-like figure, navigating his way through time while fighting a variety of evil (yet comic) adversaries. Perhaps sensing my confusion, he went on to explain that this involved working for government think-tanks, speculating on the future and advising on policy.

This started me on a rant about politicians, in particular the shallowness of policy and the tendency to optimise for media sound bites and short election cycles. His response is where it gets interesting. He made the point that although what I said was true, it was wrong to attribute all the blame to the politicians. After all, the reason politicians act this way is because that is what gets them votes: both directly and indirectly via media exposure. So both the voters and media are driving a lot of this nonsense by rewarding shallow policies with votes and air time. His conclusion was that the cycle would never be broken by the politicians themselves — change would have to start from the bottom up.

You can probably see where this is going. Just as I had railed against the politicians, developers are now complaining about Apple’s locked-down App Store. The system is opaque, unfair and at times downright stupid. Blatantly anti-competitive policies are thinly veiled as protection of the user experience. But as wrong as this may feel, should we really expect Apple to change anything? Frankly, they own the platform and are entitled to set the policies they have. And so far, consumers and developers have been voting with their dollars and applications in droves. Even if consumers aren’t fully informed, developers can’t claim to be unaware of these policies, yet still they flock to the platform. With this kind of real, positive feedback, why would Apple feel compelled to rethink their policy?

If you believe the App Store policies are wrong, then cast your vote. Don’t buy an iPhone, and (more importantly) don’t develop iPhone applications. Realistically, in the near term consumers will keep buying the iPhone — it’s still a great product. But if enough developers vote with their applications, over time other platforms will surpass it. Apple’s marketing campaign doesn’t quite have the same ring to it when there isn’t an “app for that”. And if Apple see this shift they will hopefully rethink their policies, and the iPhone will thrive once again.

Pulse Continuous Integration Server 2.1 M5

Things have been a little quiet on the Pulse 2.1 front as we have been busy squeezing tons of extra continuous integration goodness into the existing 2.0 series. Don’t think that 2.1 has been standing still, though, it’s been steadily moving along in the background. Today all that background effort has culminated in a fifth milestone build, Pulse 2.1.4, available on the Early Access Program page.

A combination of the merges across from 2.0 and continued work on new features means that this milestone includes over 100 new features, improvements and fixes! I told you it wasn’t standing still!. This milestone should also be the last before 2.1 reaches beta and is promoted to the main website.

Major changes since the previous milestone fall into two categories:

Dependencies

  • Dependency UI updates: Daniel rightly pointed out that our UI for dependencies leaked too much “Ivyness”1. Now the artifacts published from a build are more closely integrated with Pulse’s existing artifact capturing.
  • Control of build version and status: you can now configure the version and status of your builds for dependency purposes. Downstream projects can be configured to pick up only artifacts of a given or more “stable” status (e.g. milestone, release).
  • Cleanup rules for published artifacts: define if/when artifacts published to Pulse’s internal repository are cleaned up to save disk space.
  • Repository access controls: configure who has what access to the internal artifact repository.
  • Reporting of retrieved artifacts: the build status tab now shows which artifacts were pulled in from upstream projects.

Personal Builds

  • Choose build revision: You may now specify the revision to run a personal build against, rather than having it forced as the latest revision at the time of the build request. The personal build client walks you through available options (including current, floating and last-known-good revisions), or you can specify a custom revision.
  • No forced update: requesting a personal build no longer forces an update of your working copy. Instead you can choose when this is desirable.
  • Pluggable patch formats: Pulse now supports multiple formats for the patches submitted as part of a personal build. Apart from the existing format, plugins have been added to read standard patch files (unified diffs) and git patches (including git binary diffs).
  • Submit existing patches: You can now submit patches from existing files, rather than based on the changes in a working copy. Along with pluggable patch formats, this opens up many new possibilities for submitting personal builds.
  • Smarter patch creation and application: the support for pluggable formats also led to improvements to our existing format and the application of patches. The existing format now uses unified diffs where possible. On application, unclean patching is detected and reported.

Watch this space for more information about Pulse 2.1 and these new features as it hits beta. Oh, and head on over to that Early Access Program page if you’d like to try 2.1 out!


1 We use Apache Ivy internally for dependency management, but aim to make it support all types of projects.