Apr 7

This really belongs on The Daily WTF, but it will just have to live here for now I guess. All real names (except mine) have been replaced!

Preface :

A few months back I setup a project using Maven2 from scratch (You’ll hear more about this in an upcoming article). This project wasn’t large, but had strong potential to require a mildly complex build setup for multiple clients.

For those unfamiliar with this indispensable build tool, one of its major positive aspects is that dependencies on other artifacts are explicitly declared by the developer based on his understanding of the projects environment. Another is consistency - that you can ALWAYS sit down and “just build it” on a maven project with absolutely no knowledge of the specifics. There are many more.

I was stolen from this project a month or so back and moved to a new one. This project is not popular with the resourcing department of the company it is being produced by so staff theft (to other clients/projects) was commonplace. As of yesterday the project has one front end flex developer who knows that aspect very well, and one new java back end developer who doesn’t know much about it at all.

Body :

Over the last few days since the new guy started on my old project I’ve been contacted fairly regularly with various questions about how to find this, what the password is for that, etc. Today the back end developer contacted me asking for help with doing a release of the system. His Maven knowledge was a bit thin so it should have been a 5 minute case of “type this and hit enter” type stuff. Not so fast, Fred.

Something is wrong with this pom.xml snippet :

<groupId>com.company.application</groupId>
<artifactId>services</artifactId>
<version>${this.version}</version>

These instructions might start to explain why :

7) Run ‘mvn company:version’
8) Run ‘mvn scm:checkin –Dinclude=pom.xml –Dmessage=”company:version”
9) Check pom.xml and ensure the version element contains ‘${this.version}’ and the this.version element (child of the properties tag) contains the newly incremented snapshot release version number, e.g. 0.0.4-SNAPSHOT 10) Check the subversion history, it should appear something like this:

3346       31/03/2009 10:34              1              user       company:version
3345       31/03/2009 10:00              1              user       [maven-release-plugin] prepare for next development iteration
3343       31/03/2009 10:00              1              user       [maven-release-plugin] prepare release xxx

The somewhat edited conversation in which I found out about these changes (expletives removed) :

Fred: did you release those artifacts?
Bob: Partially, Harry did but forgot to do the mvn company:version command so Henry did that
Fred: wtf is that?
Bob: It updates the version numbers in the pom
Fred: it does what?
Fred: who put that in?

A small snippet of conversation after pasting the above to a colleague :

David: omg lol, they actually bothered to write their own plugin to circumvent maven versioning
Fred: Yes…

It turns out that another developer had put a significant amount of time and effort into creating a plugin and configuration to automatically update dependency and artifact versions. This allows them to work on multiple packages in parallel to produce a working product at the end.

Summary :

So, what is the big deal? Well, for starters, dependency versions should be explicitly set. Why? Because you and ONLY you know what is required. Who says that the latest data access library is the one you really want to use? Automation of this task is plain just a bad idea. Secondly, the project is no longer a normal standard Maven2 project. As such it is difficult to support it remotely without having a good look over the “plugin” and other associated changes. In short, several of best Maven’s features have effectively been disabled and made worthless by these senseless changes. But, the developer must have had a reason for doing this, right? Yes, laziness and lack of up front component and interface design. These features allow an application to be thrown together haphazardly with little thought in a fine grained incremental development style described as Programming by Coincidence. Such practices are best avoided especially by inexperienced developers, using a properly modularised project layout goes a long way to fostering a good working style.

On another, more positive, note :

Lastly, the formatting on this page was done with the following WP-Syntax plugin. The style sheet for the code blocks still needs some work, but I’ll get there sooner or later.

Update! (14/4/09)

This evening I had the pleasure of being asked (ever so nicely) to come back into the office after hours to help get a build of the project out. After getting a normal mouse connected and a usb keyboard (ps2 seemed to die) I started fishing to see what was wrong. Of course it was just a matter of adjusting some versions to match (I had [] hard versions setup to guarantee consistency). No problem there. The usual array of error messages were being pumped out. No problem there. The problem (and it was only a small one) turned out to be that the carefully used variables for versions of dependencies had been replaced (presumably by the script/”plugin”) with hard coded versions. Thus editing the variable at the top made no difference at all as it wasn’t being used. I guess it’s possible that the developer was to blame, but I strongly suspect it was the “plugin” working its magic and screwing things up. Certainly the developer was surprised to see the hard coded versions in place. Lesson learned? We will see what happens as time progresses…

One Response to “Circumventing Maven!”

  1. Sean says:

    Well written article, packed with sarcastic undertone ;)

    I agree with you 100%, developers of all languages seem to intend making something better without having a proper understanding of what exists already.

    There is no trouble with the way Maven handles versioning, why touch it?

    Let’s see if they contact you once more - with another broken build ;)

    Cheers.

Leave a Reply

( * = required field )