Migrating from Ant to Gradle

Posted on 16. Dec, 2012 by in Gradle

This will the first of a few posts in which I will document the moving of a fairly large multi module build from ant to gradle. This will likely take us a few months as there isn’t any short term need to move quickly. Our ant build process does work, it’s just very ugly and is long overdue for a rewrite.

Background

Before I get too far into migration plan and approach, I’ll provide a bit of context that will hopefully help you decided if any of what follows is relevant to you and your project.

The project that we’re looking to migrate to Gradle is a fairly large multi tiered Java/Groovy application. We have a Swing client that is installed on our users desktops and an application server component. We have our own app server that we built and we also (begrudgingly) will deploy the server side code to WebLogic if we have to. Our product is a commercial product that is deployed to our clients which they run on their own hardware/infrastructure.

The first commit in the project was Wed March 10, 2004 and over the past eight+ years has seen over 53,000 commits made by nearly 60 different people. There is between 1.5 and 2 million lines of code including tests. Some of it actually works ;)

There is a “master” build.xml (ant) at the root of the project and then each module has it’s own build.xml file. There are a number of targets in the main build.xml which in turn call targets in the module build.xml as needed. The targets cover all the usual stuff like compiling code, running unit tests and recreating developer database schemas from test data. Additionally there are targets for building installers for both the client and the app server components. There are a lot of other specific targets that are either used by developers as part of doing local builds and bits and pieces needed by the distribution process.

The main build.xml has just over 2600 lines of tasty xml goodness. The module build.xml files have between 50 and 300 lines in them. These build files have seen hundreds of commits from a bunch of folks over the years. You can appreciate that they’ve suffered a fair amount of bit rot.

Why Gradle?

We briefly looked at Maven when it was all the rage a few years ago. There are a few things that Maven did bring to the table. Dependency management and convention over configuration. We manage our dependencies by hand (we still do actually), and our project layout would have required major surgery and rework to get it to line up with the maven conventions. I decided at the time that pain of moving to maven wasn’t worth the time and effort to do so. In retrospect it was exactly the right call.

Fast forward a couple more years and Gradle appears on the scene. I could tell from the very beginning this was going to be the technology that we would use.

1) Build DSL (Domain Specific Language)
2) Builds written in groovy
3) Fantastic documentation
4) Customizable project layouts
5) Plugins and extensible plugin architecture
6) Dependency Management
7) Multi-Project builds

Dipping our toes in

In the early days of Gradle, the ant support wasn’t quite exactly there. Now, it’s fantastic but a year or so ago it was under active development. A lot of other really great features were there and pretty stable so I decided the easiest thing for us to do would be to add a couple of distribution tasks to a build.gradle that would be called once our main build was complete. This was easy to accomplish in hudson simply by installing the gradle plugin (at the time we were using version 0.9) and then adding a build step to call the gradle task in the new build.gradle file.

This worked very well and continues to be the way our sever gets packaged up.

Next Steps

The build is a bit messy in that we have the ant build doing a bunch of tasks, finishing and then a gradle build picking up some of the artifacts that were generated by the ant build. It would be nice to have that running in one technology.

We’re coming to the end of a release cycle and once that’s done, I’ll be making a few minor tweaks to our build.xml such that our existing ant targets can be called by gradle. The minor issue we have is that when I apply the groovy plugin in our build.gradle file, the build ends up with some conflicting tasks. That is we have some tasks in our build.xml like (test, dist etc.) that conflict with the ones that the groovy plugin injects. It’s a simple task of refactoring our build to use names like test_internal and dist_internal so that the names don’t conflict.

Once that is in and stable, the task of rewriting various ant targets into gradle tasks will be undertaken. To be honest I’m not sure how long that will take. Like most shops, we have no end of work in front of us and taking time to rewrite a couple of thousand lines of ant isn’t on the product road map. Likely we will just do it as we need to. That is when an ant target needs some tlc, it will get rewritten as a gradle task. In the perfect world we would just start from scratch but I just don’t see that happening, at least in the short term.

Details

Gradle Migration Part 1: Importing build.xml

Leave a Reply