Getting used to gradle, a case study : developing Qi4j

Lately Qi4j moved from maven to gradle:

Qi4j community migrated away from Maven after several years of frustration, especially around release management, versioning and cross-module dependency resolution issues, in Feb 2011. The tool of choice is now Gradle.

What ?

The case study I want to describe today is quite simple. I’m writing an application using Qi4j, it’s build is maven based. As I am contributing to Qi4j alongside the development of my own application I’m using the development branch of Qi4j most of the time. In maven terms it means my application depends on the last version SNAPSHOT. I want to continue working this way so I’ll describe here how to use the Qi4j build system for this use case.

In other words, you’ll learn how to manage the Qi4j build system for developing Qi4j and use it in maven projects.

What not ?

I will not talk about IDE support here, only build systems, namely maven and gradle.

Making it work

The main goal is to find gradle commands for different aims and make their run as short as possible.

I used the same computer for all time mesures present in this post, a Samsung netbook N150 with 2GB RAM and a Vetrex II solid state drive from OCZ.

Commands described here last from 45 minutes to 5 minutes for building and installing the whole Qi4j ecosystem in the local maven repository. When dealing with single modules all this gets very quick. For example org.qi4j.core.api can run in 20 seconds when skipping tests and javadoc.

Here are some example gradle commands. I use the gradle daemon to get rid of the startup time.

$ gradle install -Dversion=1.3.0-SNAPSHOT

This one takes forever, it will buid and install locally all artifacts (main, -sources, -javadoc),run tests and then generate the qi4j-sdk distribution archives. Took my netbook ~40 minutes.

$ gradle -x test -x javadoc -x javadocJar -x sourceJar -x :javadocs -x :distLayout -x :tarBinaries -x :tarSources -x :zipBinaries -x :zipSources install -Dversion=1.3.0-SNAPSHOT

This one build and locally install all main artifacts skipping tests, javadocs, sources and distribution archives. Took ~5 minutes on my netbook.

$ gradle -a -x test -x javadoc -x javadocJar -x sourceJar -x :javadocs -x :distLayout -x :tarBinaries -x :tarSources -x :zipBinaries -x :zipSources :org.qi4j.libraries:org.qi4j.library.servlet install -Dversion=1.3.0-SNAPSHOT

This one build and install only the org.qi4j.library.servlet artifact, skipping tests, javadocs and sources archives and ignoring changes in other modules. Took ~15 seconds, now that gets usable !

Theses are quite hairy, aren’t they?

Getting easy

To ease my work I wrote some shell scripts around gradle. They are available on github here: https://github.com/eskatos/qi4j-dev-scripts

Here is the help of the qi4j-build command:

paul@petit:~/src/github/qi4j-sdk$ qi4j-build 
qi4j-build [-p group:project] command [flags]

  -p Select the target project
    group can be core, library, extension, tool, sample or tutorial
    project is the base name of the targeted submodule

  Available commands
    clean            Clean output
    test             Run tests
    install          Install only main artifacts
    devinstall       Install javadoc and sources artifacts
    distinstall      Install distributions archives

  Available flags
    skipTests        Skip tests

  Examples
    qi4j-build clean
    qi4j-build devinstall
    qi4j-build library:servlet test
    qi4j-build libraries install
    qi4j-build distinstall

Feel free to report issues, fork and request pull.

Advertisements

2 thoughts on “Getting used to gradle, a case study : developing Qi4j

  1. So, the main “problem” is actually that you want ‘install’ goal, which triggers quite a lot. What time do you get if you do;

    cd libraries/servlet
    gradlew install -Dversion=1.3.0-SNAPSHOT

    ??

    Also, you can put “version” in a gradle.properties file in the project root, so you don’t need to type that every time.

    Further, if you study the dependency graph of goals in gradle, and tell me exactly which custom ‘fast track’ paths you want to take, perhaps we can just create those goals in the build.

    The default build is ‘classes’ and ‘test’, which I consider a minimum.

  2. Hi Niclas,

    As you state, I had no real problem with gradle. I’m sure the only problem is me not knowing it enough as from what I understand all that I did here is doable with gradle itself. I wanted to tryout some development workflow without touching a bit of the Qi4j build system.

    I tried to put a gradle.properties for the version at the qi4j-sdk root but it’s not used when I’m in the libraries/servlet folder for example.

    ../libraries/servlet $ gradle install -Dversion=1.3.0-SNAPSHOT

    Takes about 50 seconds.

    The gradle command my script issue to install only libraries/servlet is

    ../qi4j-sdk $ gradle -a -x javadoc -x javadocJar -x sourceJar :org.libraries:org.library:servlet install -Dversion=1.3.0-SNAPSHOT

    Time goes down to 20 seconds.

    In short when I’m working on a module I want to be able to compile and install its jar quickly without updating its source and javadoc artifacts, sometimes even without running its tests (adding -x test).

    I applied the very same idea to the whole qi4j-sdk build. Meaning compiling and installing all Qi4j ecosystem artifacts without updating source and javadoc artifacts and without building the distribution archives.

    Writing theses scripts I was obviously thinking about porting them into the Qi4j gradle setup once they are proven usefull. If it’s possible to add such a workflow directly in the Qi4j build system that would be awesome.

    /Paul

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s