About to upgrade to Leopard...

I'm opting for the Archive and Install upgrade, hoping to easily recover most of my existing applications and settings that way. If all goes well, my aging Powerbook G5 will soon be up to date again with the newest Apple Fanboy Technology ;-)

Controlling the Maven release cascade

In my previous post, I showed one of the pitfalls of maven's transitive dependency mechanism.

Luckily, there is a good workaround to this that will allow your team to stay focussed on development without getting bogged down too much into the release-cascade trap.

The thing to do is to create another level of indirection between your framework and the clients using it, this can be accomplished by providing a POM dependency.

For our framework it would look something like this:


<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.framework</groupId>
<artifactId>client-components</artifactId>
<version>2.0.1</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>my.framework</groupId>
<artifactId>main</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>A</artifactId>
<version>0.6</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>B</artifactId>
<version>0.8</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>C</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>X</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>Y</artifactId>
<version>0.5</version>
</dependency>
</dependencies>
</project>
Notice how this POM dependency is nothing more than a flattened dependency tree. We've pulled all our dependencies into one POM and we control their versions from there. This works pretty well, and all our clients have to do is to declare it like this:
<groupId>my.framework</groupId>
<artifactId>client-components</artifactId>
<version>2.0.1</version>
<type/>pom<type>
Using this, we can avoid the release cascade for module Y, our work is effectively reduced to:
  1. release module Y
  2. change version of Y in client-components POM
  3. release client-components POM
That's IT. Swift and fast like it should be.

The POM dependency can even be used from assemblies and the like. It behaves like a normal dependency in all aspects. Additionaly, it is a great way of quickly eliminating rogue dependencies: just exclude them in there and worry about tracking it down later.

That's it for now, I promise my next post will not take 4 months this time :-)

The Maven release cascade

Imagine you've got the following component structure in your framework:

  • main component (the included by your clients), let's call it MAIN
  • MAIN depends on functional components A,B,C
  • There are 2 helper components, X and Y, used by most modules
A rough graph of above situation could look like this:


Now, the great thing about maven's transitive dependency resolution is that when a client wants to include your framework it can do so by just declaring one artifact in their POM, namely that of the MAIN component:

<dependency>
<groupId>my.framework</groupId>
<artifactId>main</artifactId>
<version>1.0</version>
</dependency>

Maven will then automatically add modules A,B,C,X and Y to the client's project, neat !! The root component here effectively serves as a dependency abstraction, clients do not need to know anything else when they want to use my framework, this is a Good Thing really.

Imagine now that I (the framework maintainer) make a small one-line fix to module Y and I'ld like to do a new release. There were minimal code changes, and I only changed one module, so I expect the release process to go fast and swift and in a few minutes my clients will be able to use the 1.0.1 release:

<dependency>
<groupId>my.framework</groupId>
<artifactId>main</artifactId>
<version>1.0.1</version>
</dependency>

Right ?

Wrong.

Here is what maven typically will force you to do:
  1. Release module Y
  2. Update the dependency of Y in module X, release module X
  3. Update the dependency of X in module A, release module A
  4. Update the dependency of X in module B, release module B
  5. Update the dependency of X in module C, release module C
  6. Update the dependency of A B C in MAIN and (finally) release MAIN
In other words, I would need to coordinate a new release for 5 modules !! The effort is just not justifiable for that oneliner fix, so I decide to wait until I've got something more substantial to release. This is a problem.

If the effort for a release turn-around becomes far too great then this can impact your project in different ways:
  • no more release-early release-often
  • each release will contain more code changes
  • regressions become much harder to detect
  • clients get frustrated because of the slow release cycle
  • developers get frustrated by their inability to "get something out of the door quickly"
These symptoms are to be taken very seriously. They end up diverting so much energy away from the team's core business, namely to develop all those features that will make the framework dominate the world !

(This post is getting too long already, so I'll offer a solution to this in a next post.)

Apple Update 10.4.11 + Safari + Sogudi

I ran into a little snag with Safari the other day, after updating to 10.4.11. Entering an address in the address field and hitting enter no longer worked.

It turned out that Sogudi was the culprit. After installing the latest beta everything worked again.

Quote

The average quality of the code on a project equals the quality of the code written by the second worst developer on the team.

Why ?

Because the rest of the team is too busy fixing bugs introduced by the worst developer on the team.

Eric Evans, SpringOne 2007

Using the maven embedder

I was doing some work on Hudson's maven2 integration last night. It currently uses an old and unsupported version of the maven embedder. My aim was to 'upgrade' Hudson to use a more 'supported' embedder version, so the project can benefit from better maven2 build support. Those of you that don't know what the embedder is, read this mini guide as a starting point.

Getting the embedder to run inside your application is actually quite easy if you avoid the pitfall of using the old and unsupported 2.0.4 binaries. Instead, make sure to use the latest 2.1-SNAPSHOT all-in-one binary (at the time of this post it is called maven-embedder-2.1-20070830.163428-16-shaded.jar). Adding this jar to your Eclipse/IDEA project is all you need to do to get the example from the guide going.

In summary,

  1. Create a new project in your IDE, add above all-in-one jar as a dependency.
  2. Copy-paste the code from the mini guide.
  3. Change the first line to point to a little sample maven2 project.
I also recommend having a look at the embedder integration tests for examples of how to do more non-trivial things with the embedder.

Eclipse 3.3 + Mac = crash ?

So I downloaded Eclipse 3.3 for Mac today, in an effort to upgrade my (aging) powerbook development environment. I haven't been doing much development lately, but got inspired by a cool OSS project I've been using lately. Their integrated maven2 support could do with a revamp me thinks, so I plan to have a deeper look at its integration layer and see if there is anything I can do to vamp it up a little (support for profiles, settings.xml etc - but I digress).

So after having tar-x-z-vf'ed the download package, I fire up Finder, double click the Eclipse logo and get presented with this instead of the new funky Europa splash screen:


No biggie me thinks. This is the most anticipated Eclipse release crashing on the most stable and expertly-used development platform, ergo Google must be full of helpful links right.

Not so.

Update:
Installing Release 5 of Java for Mac OS X 10.4 did the trick.

Indeed, looking at Eclipse's own readme.html (always the last place to look for any seasoned developer) I can see now:

Adium connection errors



If Adium has been failing for you lately with "Could not send; a connection error occurred.", look here and here. Rumour is that M$ tweaked their IM protocol, breaking all clients that rely on things like this to implement connectivity with their MSN servers.

There are a few workarounds for the moment, one being to disable cryptographic extensions, another one being to disable connectivity over HTTP to the MSN server. YMMV though from what i've gathered on some mailing lists. Your best bet is to wait until Pidgin incorporates the protocol change so that downstream clients like Adium will work again without change.


Toyota integrates iPod


Looks like we finally might be able to do away with all those CD cases in our car !


I'll hold off buying one though until I've read some real-life user feedback on this, as I'm not up to date at all with any of this high-tech car hifi widgetry !

OsterFelder 2007

Just like in 2004, I participated in the OsterFelder Berglauf again this year. This is such a great event that I'm really considering making it a yearly tradition with my good running buddy Thomas (he's the guy on the left, picture taken before the run - notice that I'm still smiling!).

For those of you that don't really know what a mountain run is I can explain this really simple in 2 steps:

  1. Find a mountain similar to the one below (in Belgium this is actually the hardest part!)


  2. Run to the top as fast as you can, sort of like me here:
    L1070605.JPG
I had planned to take my new TZ3 during the run and shoot some pictures along the way but decided against it shortly before the start. It's quite a hassle carrying the camera in-hand whilst running, I didn't have a special pouch for it. Also, people tend to throw away all ballast when low on energy and mental strength - didn't want to risk anything ;-)

I ended up finishing in 1h53m15s, a big improvement over my previous 2h16m25s! After the finish we still sat for an hour or so just to enjoy the view and superb weather.

You can find the complete Flickr photoset here.

The story of Mel


Pure nostalgy ahead !

Every developer will at some point in his career have to deal with an incarnation of Mel.
For those of you that haven't already: May The Force Be With You when you do finally meet him!

Optimizing your maven2 build time

Or perhaps I should say, "how to not slow your maven2 build process to a crawl".

There has been some discussion on the Hudson mailing list recently about the innordinate amount of time, 40+ minutes, it takes to build Hudson from scratch. In maven2 speak, "from scratch" means you have an empty local repository. Normally, the only time you have an empty local repository is when you've just installed maven and not run any build yet. Then the first time you run a build, maven will go out to its central repository and pull down the dependent libraries (also called artifacts) it needs during the build. These artifacts are then cached into the local repository.

Everyone is free to publish their own artifacts to maven's central repository. The process how to do this is documented here.

In addition to this, maven offers you the possibility to specify your 'own' repository, to be used during the build in addition to maven's central repository. You could store your company artifacts for example on a server that is visible on the intranet but invisible to the outside world. This custom repository is specified in your pom.xml, more specifically in the <repositories> element. There are a few caveats with this however, which is exactly what this post is all about.

Caveat 1
Following good inheritance principles, most people define their
<repositories> in the root pom. This makes sense, you define them once and they are visible for all child modules. This way your custom artifacts become shared between all build instances - neat, and problem solved right ? Well ... sort of, but not quite. The thing is that maven2 will now search for its artifacts in your custom repositories before it will attempt to contact its own central repository.

So imagine you have this in your pom:


<repositories>
<repository>
<id>java.net2</id>
<url>http://download.java.net/maven/2/</url>
</repository>
<repository>
<id>java.net1</id>
<url>http://download.java.net/maven/1/</url>
</repository>
</repositories>

You will most likely get this during your build:

Downloading: http://download.java.net/maven/2/commons-collections/commons-collections/2.0/commons-collections-2.0.pom
Downloading: http://download.java.net/maven/1/commons-collections/commons-collections/2.0/commons-collections-2.0.pom
Downloading: http://repo1.maven.org/maven2/commons-collections/commons-collections/2.0/commons-collections-2.0.pom
171b downloaded

You can clearly see that maven contacts your custom defined repositories before maven central. Now if you're doing a build from scratch this will become a costly operation and can easily increase your build time by 100%. The reason for this is that 95% of your dependencies (direct and transitive) are located on central anyway, and perhaps 5% is custom stuff for your project only.

The solution to this is simple, define maven central as a custom repository before your 'real' custom repository:

<repositories>
<repository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>java.net2</id>
<url>http://download.java.net/maven/2/</url>
</repository>
<repository>
<id>java.net1</id>
<url>http://download.java.net/maven/1/</url>
</repository>
</repositories>

You see now that maven central is contacted first and if the dependency is found there maven doesn't bother contacting the other repositories. This is a good optimization for 95% of our dependencies, the impact of the few artifacts we actually do pull from our custom repos is thus greatly reduced.

I will speak about the other caveats and how to optimize them in a next post.

moving to blogspot

Every not-so-well-thought-out concept goes through a relaunch once its creator realizes his mistakes. It's not that I made many mistakes on my old blog, but there was one crucial element missing - C O N T E N T.

Speaking of which, I'm wondering if there exists a way to migrate my wordpress drivels to blogger speak ? If anyone has experience with this please drop me a comment. Its only a dozen or so articles, if nothing else I'll add them by hand.

Why is it that - SMS

Why is it that in times where gigabyte devices and high speed mobile networks are becoming more and more mainstream, we cannot send more than 150 characters in an SMS without getting billed extra ?

(Wikipedia to the rescue)

It seems that technically, there is a limit of 140 bytes in the messaging protocol used between the SMSC and mobile device. However, that protocol also defines that larger messages can be segmented and that it’s up to the receiving device to reassemble the messages.

Operators however insist to bill each segment separately. Why ?

My guess is that they are still trying to compensate for their temporary loss of any common sense during the auctioning of the 3G network licenses :-P

maven 2.0.5 released !

On #maven (irc.codehaus.org) a few minutes ago …
————
[22:53] jvanzyl: done
[22:53] jvanzyl: released
[22:53] jvanzyl: 2.0.5 go away!
————

It’s been long in the making, but finally we’ve got a shiny new version of maven2. Loads of bugs fixed it seems, makes you wonder why they waited almost a year to do this patch release (not that we are any better though … ).

Oracle sequences

Fact: Our sun will run out of hydrogen in about 5 billion years (that’s 5 000 000 000). Remember this, and not only because at that point it starts expanding and will eventually envelop the earth.

Fact: The default maximum value for an oracle sequence is 1 octillion (that’s 1 000 000 000 000 000 000 000 000 000).

Fact: Often I see that people create multiple oracle sequences in their applications e.g. SEQ_PRODUCTS, SEQ_EVENTS, SEQ_REQUEST etc. I’m wondering if this is really necessary.

So: Let’s imagine that you build a really HIGH traffic system that processes about 100 million transactions per day, and let’s assume that this eventually leads to needing 10 billion sequence numbers per day. Every day. How many days will our sequence last?

The math for this is really simple: 1027 / 1010 = 1017 days

1017 days, that’s about 2.714 years = 270 000 000 000 000 = two hundred thousand billion years. (still remember how long before the sun runs out of hydrogen?).

So why ever bother creating multiple sequences ? One argument could be performance, a heavily used sequence can suffer from performance problems due to contention. In this case however, Oracle allows you to cache a predefined number of sequence values upfront. The downside of this that the unused numbers in the cache are lost when the database is restarted.

So, let’s assume we configure a sequence cache of 10 million (10 000 000) values, and we restart our database about COUGH 1 000 times per day . Do the math, the sun will have still ran out of hydrogen before our sequence hits its limit.

If anyone can give me a good reason why you should ever use more than 1 oracle sequence object in your application i’d like to hear it.

Why is it that - iPod

Why is it that I cannot tell my ipod to play a selection of cd’s (or artists for that matter) without going to my powerbook and create a playlist for them?

Indextwirl20060912

Did i miss the part in the EULA where it says ‘WARNING: provides everything but the most basic mechanism to select a couple of tunes from your 15GB collection’ ?

Thunderbird on the mac

Just got this in Thunderbird, i had to restart to make it go away:

Overall i’m not too happy with Thunderbird on Mac, the whole app just feels very Linuxy (is that a word? if not just remember you read it here first!) and there are a few display bugs that make it just slightly annoying to use every now and then. Not that i’m considering switching though, been there done that. It’s just that it interrupts the overall smoothness of my mac experience. For those that don’t use mac, well … i don’t expect you to understand so i won’t bother explaining it … those that do use it - you get my grip !

Same goes for Firefox btw, i’m still using Safari wherever i can. The new 2.0 did not impress me at all, at least on windows it freezes way more than 1.5 ever did.

Jorg



Don’t these people have anything better to do than to make funny videos mocking my name ? ;-)

Update:
I emailed Brett Novak (the author of the original video) just for the fun of it to see what’s up, here’s what he had to say:

—————–

Jorg,
Good question. The name is actually referencing the characters name,
which is Jorg, which has been his name for the past 2 videos hes been
in. The name originally came up completely randomly when we were
filmin the first video. No real fantastic story to it - just figured
no one else really had that name - which apparently wasnt quite the
truth :) .

We actually had one other guy threaten to sue us and such since his
last name was Jorg. I had to slowly explain to this man that that
wouldnt legally be possible and that the reality is to - get over it.

:)

But if it makes you feel any better - It actually was named after you :)

——————

Brett Novak is one cool guy isn’t he !