Although my maven bitching has been mostly snarky, I have come to truly believe it is the wrong tool for a growing enterprise and, like centralized version control, will lead to a situation where tools dictate process (and design).
But, what is maven actually good at?
- Maven is great for getting started — you don’t have author an ant file (or copy one from an existing project)
- Maven is great for enforcing a standard project structure — if you always use maven, your projects always look the same
This is about where it ends for me; everything else maven does – manage dependencies, automated process, etc., is done much better and much more quickly by other technology. It’s pretty amazing that someone can make a tool worse than ant, but maven is surely it
Dependency management is not a build step
Maven is the equivalent of doing a sudo gem update everytime you call rake, or doing a sudo yum update before running make. That’s just insane. While automated dependency management is a key feature of a sophisticated development process, this is a separate process from developing my application.
Maven’s configuration is incredibly verbose
It requires 36 lines of human-readable XML to have my webapp run during integration tests. Thirty Six! It requires six lines just to state a dependency. Examining a maven file and tying to figure out where you are in its insane hierarchy is quite difficult. It’s been pretty well-established outside the Java community that XML is horrible configuration file format; formats like YAML have a higher signal to noise ration, and using (gasp) actual scripting language code can be even more compact (and readable and maintainable).
The jars you use are at the mercy of Maven
If you want to use a third-party library, and maven doesn’t provide it (or doesn’t provide the version you need), you have to set up your own maven repo. You then have to include that repo in your pom file, or in every single developer’s local maven settings. If you secure your repo? More XML configuration (and, until the most recent version, you had to have your password in cleartext…in a version 2 application). The fallout here is that you will tend to stick with the versions available publicly, and we see how well that worked out for Debian.
Modifying default behavior is very difficult
Since maven is essentially a very, very high-level abstraction, you are the mercy of the plugin developers as to what you can do. For example, it is not possible to run your integration tests through Cobertura. The plugin developers didn’t provide this and there’s no way to do it without some major hacking of your test code organization and pom file. This is bending your process to fit a tool’s shortcoming. This is limitation designed into maven. This is fundamentally different that “opinionated software” like Rails; Rails doesn’t punish you so harshly for wanting to tweak things; maven makes it very difficult (or impossible). There was no thought given in Maven’s design to using non-default behavior.
Extending Maven requires learning a plugin API
While you can throw in random Ant code into maven, the only way to create re-usable functionality is to learn a complex plugin API. Granted, this isn’t complex like J2EE is complex, but for scripting a build, it’s rather ludicrous.
Maven is hard to understand
I would be willing to bet that every one of my gripes is addressed through some crazy incantation. But that’s not good enough. The combined experience of the 7 developers at my company is about 70 years and not one of us can explain maven’s phases, identify the available targets, or successfully add new functionality for a pom without at least an hour on the net and maven’s documentation.
A great example is the release plugin. All five developers here that have used it go through the same cycle of having no idea what it’s doing, having it fail with a baffling error message, starting over and finally figuring out the one environment tweak that makes it work. At the end of this journey each one (myself included) has realized all this is a HUGE wrapper around scp and a few svn commands. Running two commands to do a source code tag and artifact copy shouldn’t be this difficult.
Maven’s command line output is a straight-up lie
[INFO] ------------------------------------------------------------------------ [ERROR] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Compilation failure
“Compilation failure”, but it’s own definition is a failure and therefore an error (not an informational message). Further, most build failures do not exit with nonzero. This makes maven completely unscriptable.
Maven doesn’t solve the problems of make
Ant’s whole reason for being is “tabs are evil”, and that tells you something. While maven’s description of itself is a complete fabrication, it at least has its heart in the right place. However, it STILL fails to solve make’s shortcomings wrt to java:
- Maven doesn’t recompile the java classes that are truly out-of-date
- Maven recompiles java classes that are not out-of-date
- Maven doesn’t allow for sophisiticated behavior through scripting
- Maven replaces arcane magic symbols with arcane magic nested XML (e.g. pom files aren’t more readable than a Makefile)
Maven is slow
My test/debug cycle is around a minute. It should be 5 seconds (and it shouldn’t require an IDE).
Apache’s Ivy + Ant is probably a better environment than maven for getting things done; a bit of up-front work is required, but it’s not an ongoing cost, and maintenance is much simpler and more straightforward. Tools like Buildr and Raven seem promising, but it might be like discussing the best braking system for a horse-drawn carriage; utterly futile and irrelevant.