Maven and Ant - the eternal debate

Howard Lewis Ship recently blogged about his woes with Maven, which has predictably triggered a long and interesting discussion/flame war.

I respect Howard a great deal: he has done a great job with Tapesty, which is still one of the most innovative and avant-garde frameworks around. But, personnally, I'll stick with Maven.
From my take, Maven brings a lot of valuable features to the table, such as:

  • Declarative dependency management. This is a big plus. Yes, I know Ivy does it too, but, for me, that in itself isn't a good enough reason to change.
  • Enforced (or, at least, strongly encouraged) standards and best practices.
  • Plugins. Sure, some are a bit dodgy, but a lot work well, and when they do work, they are a lot easier to use than doing the same thing in Ant.

Objectively, a Maven build script isn't always shorter than an equivalent Ant script. A lot of the size seems to come from the dependencies, of course - you can't really hold anything against Maven for that. And (for efficiency reasons, I believe), Maven's style of XML has always ignored attributes, which makes it even more verbose. But you get more bang for your buck with a Maven script.

For larger projects, separating the project into smaller module, each with its own POM file, works fine for me. This has the added advantage of helping ensure that you take the time to think about the structure of your project, and lets you refactor common build scripting elements.

Based on my experience, it comes down to this: basically, if you want total control, use Ant. If you are willing to comply with the Maven way of doing things (and there is a lot that makes sense), then Maven can give you a lot of added functionality free. However, the learning curve is a lot steeper than with Ant. And a complex Ant build script can get pretty scary too (I've seen enough of them!)

Howard has some valid points, though.

Yes, many of the problems do come from the plugins. In my experience, using Maven for a standard build with nothing fancy rarely causes any issues. However, I _have_ had many an issue with particular versions of plugins (Cobertura, I'm looking at you!). And I have been incredibly frustrated by how hard it is to get TestNG tests to run properly.

I like Howard's idea of a frozen set of plugin versions that are guaranteed to work for a particular version of Maven - something like that would fix a lot of the issues with SNAPSHOT-based plugins. Though relying on SNAPSHOTs has always seemed like asking for trouble.

I agree that the Maven documentation has always been pretty poor, and I always have a terrible time trying to find anything there. And some of the plugin documentation is really, really crappy.

There sure is room for improvement. Still, I wouldn't change it, as for me, the advantages of using Maven far outway the inconveniences.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Mike P replied on Thu, 2008/01/31 - 7:41pm

I've never liked Maven. What I do, is I have a short xml file outlining the components of a project, and run it through a bunch of xsl stylesheets. The generated build.xml file is then distributed with the project. That way, anyone that downloads one of the projects, it just builds. No babysitting of finicky fragile build tools. I haven't changed the xsl files for a long time now, because they just work. I've got stylesheets for jars, wars, ears, junit, and some other stuff. I highly recommend this approach, it's really a very durable method.

mykol replied on Fri, 2008/02/01 - 12:02am

this debate would never end. that fact of the matter is each build system has it's own strengths and weaknesses. but neither is a golden hammer. if people want to have a standard lifecycle and build system that is managed by the system via established conventions, go for maven. if your project meanwhile needs to have more micro-configurations and couldn't capitalize on the conventions provided by maven, then go for ant ( + ivy). there could be lots of if-else statements still. simply put, use what works for you.

Mike P replied on Fri, 2008/02/01 - 6:32pm in response to: ronald

Ok. I've been asked that before, and I never got around updating the documentation that I wrote for it. I'll see what I can do.  I was also hosting it on my own website with my own blog engine, but since I haven't looked at that for a while, this whole web design aspect has become a little of headache for me.  I didn't want to use those tacky template like public blog engines, and thought it was always cool to host something on your own home brewed server.  I did that, but when you leave it for a bit you start to wish things worked better.  Anyway, perhaps I should just slap it onto sourceforge and be done with it...

It's kind of neat, it has an ant-server to faster (re)builds. Ant and javac stay in the jvm across multiple build sessions that way. Normal people use an IDE and build from Eclipse or something but I'm not normal and use the command line and vim for editing. It has a debugger with hotswap (class reloading) capabilities as well. Any project you build using ant, you can run using 'ant run', and debug using 'ant dbg'. When in debug mode, since it knows where the source files are because it knows how to build it, it automatically recompiles updated java files and passes it to the jvm.

Alternatively, for buids, you could also create xml include files using entities. I've done that on a couple of projects and that worked pretty well too. The include files should remain the same across the various projects.

 

Mike P replied on Mon, 2008/02/04 - 6:15pm

Most dependency problems go away if a company simply put all their own source code in one big tree, strategically placed in logical java packages that make sense. Let the compiler pull in most of the source code. Minimal headaches and the distro usually ends up being nice and tight.

John Ferguson Smart replied on Mon, 2008/02/04 - 7:22pm in response to: okidoky

Hmmm, seen that done in some places: a bunch of functionnally unrelated applications bundled together in the same source tree because they were deployed on the same site. The result was terribly slow builds (admittedly, CVS tagging also had a lot to do), a complicated build script, and a bloated testing process because testers were convinced that, since the whole application had been rebuilt, everything needed to be retested.

Mike P replied on Tue, 2008/02/05 - 7:35pm in response to: mr_john_smart

I've introduced my own build process in a number of companies now, and all use the single java tree model. No build performance impact at all. On the contrary, things build MUCH faster because there is no library generation and dependencies (other than 3rd party libraries of course).

The build scripts tend to be MUCH simpler as well. You simply feed only the classes you need to javac. Javac pulls in all the other classes automatically. Having other java files in the tree that you're not using doesn't slow down the build at all. Of course, you need to feed all the java starting points, like the one with main (if it starts that way), and all the java files containing classes that are instantiated through introspection.

I've never understood the resistance to the single java tree approach. It works so well.

The only thing that's not great is that IDE's like Eclipse want to compile everything.  I'm more of vim guy, but the other colleagues using Eclipse never complained.  Memory is cheap these days.

Jeroen Wenting replied on Wed, 2008/02/06 - 2:39am

"Most dependency problems go away if a company simply put all their own source code in one big tree, " So Maven is good for very small companies that only have a single product. If you have groups creating standardised components used by other projects (maybe with references between those components for good measure) Maven becomes a major PITA.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.