There are few technology decisions I’ve made during my current tenure at Jobster that I regret as much as using Maven for our build system.
We started out with a pretty simple but workable ant script. However, I came across Maven and was intrigued by its promises: standard targets derived from a project descriptor and sparse property overrides, automatic (slightly less than attractive, but informative) site generation, and a host of plugins that will grant us instant functionality as needed.
How deluded I was.
While I (more-or-less) got the above, these features were tightly coupled with the following:
- crappy or non-existent documentation
- poor performance and memory utilization
- meaningless error messages
- poor tool integration
My current favorite issue with Maven is that it never releases memory acquired as part of a unit test until the build is done. So each unit test keeps leaking memory into the next test. Our build runs out of memory if it tries to do anything besides run unit tests. So, for awhile, the workaround was to have a two-step build process: build the product, then run unit tests. This was less than convenient, and people got out of the habit of running unit tests.
We’ve found another workaround for this.
maven.junit.fork=on
This causes each unit test to be forked into its own java process. But then our unit tests take over 4 times as long to complete. And its not like unit tests in Maven were fast to begin. For comparison purposes, IDEA can run all of our tests (including our integration tests that actually hit the database) in less time than it takes for the maven build to run just the unit tests (and this is with forking turned off).
Oh, if only I had listened to those that had gone before me.
You surely don’t read Hani’s BileBlog 🙂
He often does make sense if you can ignore his colorful language.
My observations on Maven on February 2004 were:
Then comes maven. Conceptually I have problems with a build system, which downloads components as needed, assumes internet connection etc. It just doesn’t fit into a easy to use model, rather it tries to mold us to its mindset.
I still feel the same way.
You can use “fork=once” to fork one JVM for all unit tests. This has both benefits.
In terms of IDEA integration, it is an apples to oranges comparison. Try comparing Maven to Ant, as that is the alternative to your build system.
We use maven quite successfully – I can run ‘maven atlassian-idea’ in the root of *any* project that we have, and it will produce an IDEA project file.
We can also put *any* project into our build farm, as they all have the same targets.
Hi, Scott. Thanks for sharing your experience.
I have no doubt there are many successful projects happily using maven. However, our project wasn’t able to take (sufficient) advantage of maven’s strengths, and we were getting hung up on its many shortcomings.
The only reason I compared Maven’s unit test runtime to IDEA’s is because I didn’t (yet) have an ant build to compare against.
Thanks for the tip about forking the unit tests. I’m using that in our new ant build. I didn’t realize that was available in maven. It’s a shame there’s no mention of this at the actual test properties site. However, I just tried this on a branch that still has maven in place, and a majority of the tests fail due to a LinkageError when loading the Node class. A google search suggests that this is a known problem with some configurations. I do know I don’t have this problem with similarly configured unit tests in ant, and I’m tired of reading/rewriting jelly files to track down all the bugs.
It’s interesting that you bring up the ‘idea’ target. Obviously you’ve done some customization around this functionality, given the atlassian-specific target. Personally, I found the idea plugin very frustrating. While it was good for creating an initial set of IDEA files, it wasn’t terribly useful once you’d customized the IDEA project with appropriate settings and you updated the version on a dependency JAR. Even just recreating the iml file would overwrite other configuration that we’d have to go back and re-add. So we’d end up having to update the project by hand every time an existing library was updated or a new one was added.
But devs in our group still want this functionality. So I’m now basically adding an ‘idea’ target to our new ant build, but with more intelligence about how it updates dependencies without overwriting previous config.
And that was one of my biggest disappointments with maven. In the end, many of the plugins didn’t work, or only got me halfway there, or had an annoying bug, or had functionality that wasn’t documented correctly. So I ended up digging through jelly files for hours, or rewriting the plugin, or just implementing it in my maven.xml file.
If i’m going to spend all that time implementing my own build features, I may as well just use ant to begin with. There may not be as many bells and whistles, but the documentation is complete and up-to-date. And with ant 1.6.2, ant-contrib, and a good dependency tracker like Ivy, there’s very few bells and whistles I can’t provide myself.
[…] eof~
4/13/2005 maven:uninstall
Scott wrote this in the wee hours:
Mission Accomplished Our build is now Maven-free, and I couldn’t b […]
The test memory leak is JUnit’s fault. It keeps instances of all your tests until its run is complete. Null out any fields that have been set on tearDown.