In his recent post, Java Build Systems: A Sad State of Affairs, Jess Johnson describes the many problems with both Ant and Maven, and how Maven solves none of Ant’s issues, but instead invents a few new ones of its own. But for me, the real of the gem of the post was one of the comments it inspired, that mentions a novel new piece of software called prebake, that could be to build systems what SmallTalk and Simula were to OO programming languages, but more about that later.
Using Ant For Your Build Scripts
First, I’d like to describe where, for me, Ant really goes wrong, over and above the points that Jess makes. With Ant, out of the box, you end up with a build system that is inefficient, and is only reliable provided you correctly define the dependencies of all tasks. Given that requires you have a knowledge of the entire build system, and requires lots of testing, that in itself isn’t a trivial task.
Once you do have all your dependencies defined correctly, and your build has become reliable (but still very slow) the next task you are likely to undertake is to make it perform better. You will likely do this using the <uptodate/> task to only perform targets if the source files have been updated since the output files were last generated, and/or the <fileset/> and <modified/> tasks to limit the files your target processes to only those files that have been changed since the last time you ran the target.
This works provided you don’t have too many source files (they will all needed to be stat-ted or MD5ed before Ant can determine whether it needs to perform the task or not), and creates two new problems:
- Your build system becomes much harder to comprehend and much more time consuming to test.
- Your build system starts breaking every time you modify it because Ant doesn’t check-sum the targets, and ignores your build restrictions if the targets have changed.
Every time your developers sync and get a change to scripts, they also get a new build problem to debug … oh Joy! You can also fix this by treating all Ant build files as inputs to each conditional target, but there are even subtleties here, like the fact that developers may be using the -D flag to pass in properties that change whether things need rebuilding, or that you need to keep an eye out for each new .properties and .xml file that is build related and ensure it’s a matched as being a source file, or that your <uptodate/> tasks will keep breaking as developers change the inputs and outputs to tasks without also updating the from and to patterns, which doesn’t get immediately noticed, but just ends up creating another subtle build bug to debug! You can work around all of these problems, but you’re going to end up with a build system that is unwieldy and unreliable, and will be the constant focus of criticism in your retrospectives.
The Maven And Ivy Approach
Maven and Ivy try to avoid these problems entirely by encouraging you to divide your build up into small parts that can be checked into a repository, but ultimately by denying you first class access to your own source code, and by introducing a versioning problem you never previously even had, they just create a bigger problem than they solve in the first place.
Prebake To The Rescue
All of this is what intrigues me about prebake. At a cursory glance, it seems to solve all of these problems and many more, and it does this while still providing first class access to all source code. It tantalizes by seeming to promise that creating efficient and reliable build systems will become a near trivial operation. An example of this is how explicit dependencies are done away with in preference to what is essentially the parallel of Ant’s from and to properties from it’s <uptodate/> task. The genius here is that it becomes impossible to forget a dependency, and if you don’t define your from and to properties correctly you’ll know about it immediately. This is coupled with built in check-summing of each target, so that the build doesn’t break when you update it, but only the absolute minimum of targets are rebuilt.
Admittedly, I haven’t even downloaded this still alpha software, nor I have I even read all the documentation, and am still unclear of how well, in reality, prebake will handle dependencies which are not intrinsically file related, but everything I have read to date inspires me with confidence. If this isn’t the build system that ends up winning the battle, then I still have a hunch it will end up being considered a seminal work in that direction.