Maven & Gradle

Recently, a report came out "downgrading" Maven to "hold."  Interestingly, the rationale is given as "Maven has long been a staple of build automation in the Java space. However, given its lack of flexibility and support for automation best practices, especially in the Continuous Delivery domain, the use of alternatives such as Gradle should be considered." Maven does have a few problems, to be clear. My personal wish list for Maven includes:

  • The ability to (optionally) split the POM into two files, a pom.xml and a dependency.xml.
  • The ability to use JSON instead of XML to define a POM.
  • Too many features require bolt-on plugins (e.g. Cargo).
  • The lack of a "Test WAR" concept, specifically the ability to generate and run a WAR with additional configuration resources.  For an example of this, check out the Play Frameworks concept of play test - you can run the same application in a test mode with test resources.  Maven has excellent support for splitting out the test code for JARs - I'd like the same thing for WARs.
  • The learning curve for Maven is brutal, mostly because the docs don't clearly explain the lifecycle and plugins clearly - people usually muddle through without understanding how it works.

You'll note that nowhere do I mention a lack of flexibility. Maven is absolutely critical  for us making good on our Continuous Delivery goals. Maven is only designed for one thing: generating, testing, and deploying artifacts (in particular JARs & WARs). Maven is not intended as a general purpose scripting language - any attempt to treat it that way will only lead to frustration.

Gradle is an interesting attempt to fuse a specific goal (building artifacts) with a generic goal (a generic scripting language).  As of this writing, here are the main blockers as I see it for Gradle adoption:

  • It's not a 1.0 release yet.
  • It has to improve the IDE support. I can open a Maven pom.xml file directly in Intelli/J, Eclipse, or NetBeans. I can generate IDE files from a Gradle project, but now those files have to be kept in sync manually.  There is an API provided by Gradle for embedding into IDEs and CI environments, so this is solvable.
  • Nobody but the "cool kids" are using it yet. Seriously - check out the relative job trend usage for Ant, Maven, and Gradle.
  • Is Groovy really the right solution for build files?  Having used Grails for a large scale project, the pros and cons of a dynamic language really start to come to light.  Not counting the dependencies, even the verbose XML of a Maven pom.xml rarely exceeds a few hundred lines.  Because of the Maven lifecycle, you can at least point to a "right" way to build a project in a standard fashion. It's far too easy to imagine a Groovy-based project file (just like Ant) getting completely away from a dev team.

The first three points are completely solvable with adoption, although that can be a tricky thing to pull off. The last is the really tricky one.

The first version of Maven relied on a technology called Jelly.  Jelly allowed you to write scripting in XML.  This was regarded as a cool thing to do a decade ago - people were doing things like creating "XML application servers" that let you do everything, no, EVERYTHING in XML.

It turned out that doing everything in XML was a less than fantastic idea, and rumor has it the creator of Jelly actually apologized for it.

Keep in mind that you can easily add Ant, Java, SQL, or other bits of dynamic code to Maven.  We used to think it was a good idea to mix a bunch of code up in our JSP pages, but now we think that's a terrible idea - why would we want to mix a bunch of dynamic code in our build files?

I'll be watching Gradle carefully, along with sbt - tools are the foundation of our Continuous Delivery model, after all - but I think Maven still has quite a bit of life in it. I certainly wouldn't start ripping Maven out wholesale and replacing it with Gradle. I don't think Maven is perfect - but it works, and it works well.