Why I don’t like Maven
More than two months ago I tweeted something like “As if this day didn’t already suck Maven 3 was released”. I got a reply from @kirean73 “Mind sharing your experiences with Maven?”. Fair question. As it takes more than 140 characters I decided to write a blog-post about it. And since I did not have time to do it there and then I asked @kirean73 to remind me after a month had passed. A month ago I got the reminder but this post turned out to be really hard to write. Mostly because there is nothing seriously wrong with Maven…
I’ve been looking forward to write this post for some time. I really don’t like Maven but I realized that I don’t exactly know why. It will be useful to explore that. I don’t want this to be just another of the many maven rants out there. I’ll try to be fair but I also reserve the right not to think that some things are good even if I can’t present a better alternative :) This is a subjective post.
I have yet to try Maven 3 though so things may have improved in that version.
When it comes to my experience with maven: My first experience with Maven must have been in 2004 or so. We investigated if we could use maven for a project we were starting. A few of us looked into it and found Maven to be a bit opaque “what does this thing actually do?”. Since then I have that part figured out of course but back then we stuck with our ant-script. That was probably the wrong choice. The feeling of an untransparent build-system still sticks somehow. I find that Maven is sometimes a bit hard to penetrate. I find that my maven usage is a bit google intensive and that maven is a little bit of a black box at times. I don’t know if it’s just me or if the Maven philososphy is a bit like “don’t you worry about your build, we take care of it. Just write mvn clean install and you’re good to go”. I’m outsourcing the details of my build to strangers.
I have used maven on and of through the years. Maven does a decent job most of the time. Can’t complain. Above all Maven gets you started quickly; just arrange a project so that Maven finds it’s way and your’re all set. Maven has also made wonders for the Java community when it comes to how to distribute your binaries. Before Maven there weren’t really any good options. In fact Maven is pretty decent over all so what’s the problem really? Maven stands in the way of innovation, Maven is not excellent, Maven assumes there is one right way to build for everyone, Maven does too much and sometimes bites off more than it can chew, Maven is hard to extend, Maven is a bit of a black box, Maven is slow, Maven is unreliable.
Ok, that was a lot of unfounded opionons. They all deserve to be motivated. I will explain what I mean with each of them one by one in reverse order:
Maven is unreliable
Ever deployed something you just built and found that for some reason your last change did not make it to the build? No? Good for you! An experience I know I share with many is that I build clean quite often with Maven. It happened a few times too many that I deployed something after a dreadfully long build-cycle just to find that everything was not in there in mysterious ways. Build clean, wait again.
I especially find Maven unreliable in combination with eclipse. The Maven plugin for eclipse can really mess up eclipse’s build-cycle. Infinite loops, persistent errormarkers that are never removed etc. You often get different results from the prompt and from within eclipse. It happened a few times that we had infinite loops of rebuilds in Eclipse (ok, I can’t prove that the loops were infinite since we did not wait for an infinity but we did see the same projects being rebuilt over and over again). The incremental build is about the only truly excellent feature of Eclipse and with Maven that pretty much goes down the drain. If there is one area where Maven really does suck it’s the eclipse integration. As usual though Maven gives you enough to make you think it’s worth the hassle. I’m not sure if it is.
Maven is slow
I heard that Maven 3 is more snappy. Good thing. Maven 2 is prettty awful performancewise. Why is that a problem? Slower builds, slower feedback. Slower feedback, worse quiality. Simple as that. Hardly anyone that use Maven does not know how to disable tests in a build just to make the build times bearable. While it’s fair to point out that most developers could learn a thing or two about how to make their tests run faster maven still has a pretty long ramp up time when it does not output any useful feedback to the developer.
Maven is a bit of a black box
This is one of my key issues with Maven. Partly the black boxyness is due to java as the language of choice for creating plug ins. In Buildr for example, if I want to know how something works I can just find the source and look at it (Buildr is made in ruby). If I get a stacktrace I can do the same. If there is a bug in the plugin I can fix it by editing the plugin source. If I feel like it, I can generate a patch and submit it so I won’t have to fix it again when upgrading.
While I can download the source for a maven plugin and do the same I also have to think about how to distribute my plugin to others after I figured out how to get the source and compile it. If I want to know how things work I will at the very least have to find the documentation for the plugin (if there is any good documentation to be found). Due to the maven strategy of plug-ins the documentation is fragmented and scattered.
Maven could compensate for this better. For instance when I run mvn –help it would be nice if I could somehow see what the build-cycle will look like. What will happen when. It would also be nice to get a listing of all pugins I have in my Repo and their options, heck, it would be cool if I could see a listing of all plugins available in any listed online repository. I bet there are plugins that can provide this information but then I would have to know about them. I could google but I think I should also be able to find out via mvn –help.
If I supply an option to maven like -Dmaven.test.skipp it would be pretty nice if Maven told me that maven.test.skipp is not a valid option. Why not tell me which options are available whenever I supply an unrecognized option? Sure, Maven can’t know which options plugins accept… or could it? At least maven could have been designed to be able to do this if it was considered important. But obviously it wasn’t… consiered important. Maven doesn’t even tell me about my alternatives when I run jetty:start. It would indeed be helpful to know my alternatives then and that one of them is jetty:run. In all projects that used maven I have heard a lot of questions among teammembers: “Do you remember how you do X in maven…”. We’re not talking about hard stuff. Just basics like how to run the integration tests. Symptomatic of an opaque system.
Maven is hard to extend
When it comes to plugins maven could do what SBT does. Just supply the source in the correct directory and they will be compiled when needed. It would simplify distribution, versioning of your whole build in one place etc. Of course with an interpreted language it all becomes even simpler and perhaps build tools should be done in interpreted languages (as is the case with Buildr and Gradle for instance). Given that the source is always available it’s much easier to learn those inner details that so easily get lost otherwise.
Maven does too much and sometimes bites off more than it can chew
I often feel that Maven is not satisfied with being my buildtool. It wants to be my whole development process. Maven dictates how I should do my versioning, packaging, deploying, directory structures you name it. There are very few areas of development where maven does not meddle. In this Maven sort of becomes a jack of many trades, master at none. I think the maven plugin is what will kill Eclipse (ok, Eclipse wont die easily but the maven plugin totally takes over eclipse’s build and turns it into an average IDE from the early 2000s buildwise…). I often feel that Maven’s approach sort of works but is a bit dated and far too rigorous for the simple case… but hey… it sort of works so why complain?
Maven assumes there is one right way to build for everyone
I have to conform to Maven to a large degree and the compromise is always on my side. This is not by necessity a bad thing. The maven folks are right that all builds do essentially the same thing so why shouldn’t we standardize the process and solve it once and for all? To be honest, if Maven hadn’t beaten me to it I would probably have started (and if I know myself not finished) a project to create something like Maven. Maven’s idea makes total sense. The bad news is that there is no one true model for every problem. Even if it sounds totally crazy, the way you do your builds can be a competitive advantage. How you build is a key component to how you get your feedback and how often you can deploy. Your build tool is a strategic tool!
There are also ways in which Maven punishes totally valid choices. For instance in multi site it’s hard to get an aggregated view. If I chose to rely mostly on acceptance tests and not unit tests I can’t see how well every module in my system is covered by those tests. The test coverage reports with cobertura for instance are generated per module from the tests in each module. I cannot see how well module B is covered from module A. You may argue that this way of testing a system is not pure, good, cocher or whatever you call it but that would just be you imposing your opinion on everyone else. Maven should not make that choice for developers.
You may make the point now that it’s not Maven’s fault that the cobertura plugin works how it works. Fair, and it would be ok too if it would be a simple thing for me to adapt to my needs but as far as I’m aware there is no way I can express my needs in XML so that the cobertura plugin understands me. If it would be a simple thing to fix given that I have downloaded the source for the cobertura plugin I don’t know. Perhaps it’s in Mavens nature?
Another point is this thing with versions. What if I release every 10 minutes? I can really get a versioning nightmare in Maven. If I use snapshots for everything it can become a performance nightmare (so that I in efect can’t release every 10 minutes).
Couldn’t agree more that each build is not as unique as a snowflake. They all look pretty much the same from a long enough distance but so does snowflakes. Mavens build process works ok for everyone. Mavens process is optimized to suit average needs (and succeded quite well). On average Mavens model works well but it will just be average :)
All builds do essentially the same thing but the focus can make a world of difference.
Maven is not excellent
If Maven was the end of the road when it comes to builds; the ultimate one and only answer to how builds should be done then that would indeed be excellent. Unfortunately I doubt that there will ever be a one and only ultimate build solution out there. I have no doubt that Maven is a perfect match for some but I know it’s not a perfect match for everyone. It is all fine if Maven would recognize this but it doesn’t. Maven really tries to be the ultimate build solution and is bound to fail like every other tool that attempts this.
There are so many dimensions that you could optimize for and it’s highly unlikely that one tool would excel in all of them.
Maven stands in the way of innovation
Maven does a good enough job for most problems to have become popular. When a tool becomes as popular as Maven most people don’t even look at another tool. There are other initiatives out there that deserves more attention but teams play safe and choose the tool that everyone knows (though most people I have met know little more than how to type mvn clean install).
Maven is now an established tool. As such there is not much innovation happening at Maven’s initiative. Most new cool things like shells etc are created in other tools first.
I really can’t say why but I also have this strong feeling that the Maven team does not share my values when it comes to how I want to build my software. I have specific needs when it comes to testing, deploying etc. I don’t really believe in the one tool to rule them all idea.
If I’m going to outsource something as important as my whole build process to a team of people I don’t know I better feel that I trust that team to look after my needs. I don’t. Especially since the Maven team has already failed twice to create an excellent build tool. Why would they succeed a 3rd time? What indications are there that the Maven team learned any important lessons from Maven 1 and Maven 2 that will make Maven 3 the final one tool to rule them all?
So pardon me for not jumping up and sown with glee when I heard that Maven 3 was released. I’m sure I will find out soon enough just how excellent Maven 3 really is (wether I want to or not). As for my curiousity and learning that comes from it it is currently aimed at gradle and SBT.
I think Maven works fine but in the past some logical choices have been made that do no longer make sense (XML, a compiled language for plugins etc). Other tools have fixed those and it will be hard for Maven to change in fundamental ways (and Maven shouln’t, it does what it does). When I will have to use Maven I wont bitch about it but I will sure keep my options open. Will you?