Testing Akka with Specs2

This year I have been working on several systems based on Akka, usually in combination with the excellent Spray framework to build fully asynchronous actor-driven REST servers. All in all this has been going very well but recently I had to reinvent a certain wheel for the third time (on the third project) so I thought it might be good to blog about it so others can benefit from it too.

The problem is very simple: Akka has great unit test support but unfortunately (for me) that support is based on ScalaTest. Now there is nothing wrong with ScalaTest but personally I prefer to write my tests using Specs2 and it turns out that mixing Akka TestKit with Specs2 is a little tricky. The Akka documentation does mention these problems and it gives a brief overview of ways to work around them, but I could not find any current example code online.
Read more →

How to Fail at Writing Bad Code

Trying to produce bad quality code is quite hard when you are using Test Driven Development (TDD), even when you are doing it wrong on purpose.

Recently Iwein and me were preparing some labs for a developer training and the plan was to create some really bad quality Java code as a starting point. Students would then be asked to clean it up and add some new features, all this of course with the intent to show the effect of bad code quality on your ability to quickly add new features. This was going to be a piece of cake!

After some brainstorming for interesting standalone programming challenges, we came up with the idea of writing a JSON to XML converter. It should be able to take any valid JSON string and convert it into a simple XML representation. Out of habit and without really considering the option of skipping this step, we started with a simple failing test. Here it is:

public void shouldConvertTopLevelEmptyArray() {
    assertThat(converter.convert("[]"), is("<array></array>"));

Simple, right? To implement our converter we decided to use the well known "red, green, as little refactoring as possible" anti-pattern, which we expected to result in lots of copy-paste duplication, very long methods, and the other typical code smells we all know and loath. Our first implementation approach was to go for some all-time favorite candidates for producing bad code: string manipulation and regular expressions. As Jamie Zawinski famously said: "When some people have a problem, they think: 'I know, I'll use regular expressions'. Then they have two problems." We had created a sure thing recipe for disaster. It was going to be all downhill from here, or so we thought.

Read more →

What I learned about Git during a 20 developer commit frenzy

Last week we had one of our infamous tech rallies and we had a lot of fun trying to build our own Posterous clone in a day, i.e. turning emails into blog posts.

The project sources are hosted on Github. We were working on this one-day project with about 20 developers spread over 4 teams and one of the things I noticed is that most of us did not have more than the very basic Git experience. This meant that we ran into a lot of merge conflicts and solving those is not always easy. Below is a little rundown of the Git learning stages we went through in team MongoDB to deal with this.

Read more →

Pimping the Scala XML library

Earlier this week I ran into a missing feature in the Scala xml library and I ended up adding this feature myself, which turned out to be pretty simple.

I was trying to extract the text contents of an element in a piece of XML using the handy \ and \\ methods on scala.xml.NodeSeq. These methods allow you to extract sub-elements from an XML node in a way very similar to XPath, something like this:

val xml = <a><b><c>text</c></b></a>
val c1 = xml \ "b" \ "c"
val c2 = xml \\ "c"
val text = c2.text

The problem I ran into occurred when I tried to use these methods to extract an element when one of its attributes had a certain value.

Read more →

GIT 101

After hearing a lot about distributed source code management (SCM) systems lately, I've been playing around with GIT and I like it a lot. As a longtime user of traditional SCMs like CVS and Subversion, working with GIT is something of a revelation and so nothing seems more natural than spreading the gospel a little 🙂

To help other people learn about GIT, I've collected some of the most interesting GIT 101 stuff I've found around the net.

Read more →

QCon San Francisco 2008 - Impressions

Last year I came back from QCon San Francisco filled with new ideas. DSLs were clearly going to rule the world so I'd better start using them any chance I got. No surprise then that I was back for more this year, hoping to find out about the hottest new bleeding edge trends. Unfortunately the first two days were slightly disappointing. I did visit some interesting cloud computing introduction talks and Kent Beck's talks were pretty funny, but nothing really blew me away.

Luckily the last day was more like it. Here are some impressions of what's hot and what's not:

- Relational databases are very uncool (or "unkuu" as Kent Beck's son would apparently put it)
- Alternative storage solutions like CouchDb, AtomServer, and Neo4J are very hot.
- Google's BigTable and MapReduce are very influential and lots of innovative new projects are based on them.
- Everything should have a RESTful API.

There were a lot of interesting sessions on friday but the best two were definitely:

- Unshackle your Domain, a DDD session that talked about some very interesting domain modeling techniques. See Erik's blog for more info on that session.
- AtomServer - The Power of Publishing for Data Distribution. These guys not only discussed a very interesting RESTful data storage solution, they were also very entertaining and their new dating site http://www.AnyoneWillDo.com/ will undoubtedly be very successful.

All in all it was very much worth it coming to San Francisco this year and hopefully I'll be back for more inspiration next year.

Installing Oracle XE on Ubuntu JeOS on VMware Fusion on OS X Leopard

It seems Oracle on linux is the only way to get Oracle on my Mac.

I recently switched from Ubuntu to OS X 10.5 (Leopard) as my main development OS and I quickly ran into a major hurdle, this being the fact that there is no reliable way to install an Oracle database server on Leopard. Oracle does offer a version for OS X but they are obviously not very serious about the Mac as a platform because it is an outdated version of 10g and, more importantly, it only really runs on OS X 10.3, a version that has been outdated for almost two years. I went on a Google hunt for information on how to install this older version on my shiny new Leopard-enabled MacBook Pro and I found some forum posts and an outdated site listing the tricks for getting it to work on 10.4, the previous version of OS X, but no clear instructions for getting it to work on Leopard.

Read more →

Using the unsaved-value attribute to prevent TransientObjectExceptions in Hibernate

We ran into a TransientObjectException in our Hibernate-enabled code. At first the exception was very hard to reproduce and only occured in very rare cases. Sometimes during our integration tests and sometimes during our smoke tests.

We tried just about everything to find out why Hibernate interpreted the relevant objects as being unsaved (ie transient) even though we verified that they were indeed saved in a previous Hibernate Session by looking at the sql logging.

It turns out that Hibernate does not see the diffference between the values "0" and "null" when looking at the ID property (a java.lang.Long) to check whether the object is persistent. Because our Oracle sequence starts at 0, the first object that was persisted had an ID of 0. When that object was then used in a later Session, Hibernate did not recognize that value as valid and interpreted the object as transient.

We fixed this by adding an extra unsaved-value attribute to the relevant mapping. Like so:

<id column="ID" name="id" type="java.lang.Long" unsaved-value="null" length="10">
  <generator class="native">
    <param name="sequence">MY_SEQ</param>

That solved the problem. Whether this is a bug or a feature in Hibernate I'll leave as an exercise for the readers 🙂