Gradle and groovy

Gradle is a while on the market. That’s a fact. But as it is with all those new cool stuff, we keep on using “old”, bulletproof, production-proven Maven. But quite recently, a small internal project came up and we decided, it is perfect opportunity to try out Gradle.

By just opening User Guide – Introduction you would learn that Gradle is flexible like Ant, supports build-by-convention like Maven, uses powerful dependency management based on Ivy and last but not least uses Groovy instead of XML. That sounds more than promising, thats sounds just like election kind of promise promise (yup – as I write this post, parliamentary election in Poland is just around the corner).

So what really makes Gradle unique?

Tasks oriented “Ant alike” script

First feature I wanted to try was ability to create single task without having to bind it to some phase of lifecycle. With all good stuff that comes with Maven, impossibility of running single task, like populate my local DB was pretty anoying1. Here Gradle is pretty awesome. Creating tasks, making them depend on each other or simply ordering them works great. What’s more, it could be evaluated on the fly not just hardcoded!

Custom ”inline” plugins

What I really like the most about Gradle is its flexibility. If you need any custom behaviour, just include it in script itself. It is Groovy after all! Moreover Gradle gives you much more elegant way to do it. It is enough to add buildSrc folder to your project and that is all you need to write local plugins.

OK, let’s test it. For the project itself, we are using Redmine to track issues and we track in which version the issue is fixed. Let’s generate release notes in JSON format for it. All it takes is to create a project in buildSrc folder.

For me it is fine. I never wrote a plugin for Maven so I cannot compare it but this one was really straightforward.

Gradle way build properties and gradle-properties-yaml-plugin

Configuring the build environment in Gradle is quite similar to the way Maven does it. In simplest scenario you have properties defined in gradle.properties in your project directory and you can overwrite it with the one defined in Gradle user home.

Seems to be OK.

Default environment properties are checked into Git (or something else) but you can easily redefine it to suit your machine. But unfortunately this is a truth only for Maven and its profiles. What’s wrong with Gradle-way? Gradle.properties is not settings.xml – I mean it is not XML, but a flat property file. There are no profiles you could switch, no inline property resolving, no server credentials and no password encryption!

Let’s assume I keep an IP of my database in property hibernate.connection.host. Moreover I do it in all my projects.

So what would I do switching from project to project or from local Vagrant to not-so-local non-Vagrant machine? Should I keep copies of ~/.gradle/gradle.properties for every possible project and environment permutation?

For me, this is the place Gradle must definitely improve.

The best I could get was Gradle Properties Plugin from Steven C. Saliman. Nice plugin but still not enough. But look at the source code – according to Cloc it is 258 lines of code (excluding tests)!

258 lines? This is the effort I can risk. So I spent a day on writing and publishing my own yaml property plugin. Why YAML? I used it for Puppet, I spotted it in Grails 3. I decided to write it in similar way as Grails does, extending this by something Maven-profiles alike. To be honest, I haven’t used my own plugin in production yet, but what you should see here is, how easy it is to extend Gradle to fit your needs.

Final word

Footnotes

I’m aware that with help of profiles or combining Ant with Maven (where Ant takes from Maven properties and classpaths), it is possible to create something task alike. ↩

Yes, we do use DbUnit for populating database with various test data. ↩

Mariusz Wiktorczyk

Software Developer, IT consultant, Software Ninja.

He is mainly working with Java and databases. From time to time also a DevOps: some experience with Puppet/Docker/Vagrant, database administration, simple Groovy scripts, setting up CI/CD in Jenkins. He is not devoted to Linux nor Windows, uses both if needed. Privately he is an eager squash player and a mad biker.