Gradle – A Maven perspective

As reader’s of my blog would know I am a bit of a Maven fanboy. I had started using Maven around 2007-8 and have never looked back. However, as is the case with everything else ‘change is the only constant’. There are other players in this area now, and Gradle looks to be the most promising of the lot. I have decided to give it a shot and I have shared the gist of my findings / learning in this article (of course a single article would only barely scratch the surface, but it is a start none the less). If you work on java based projects, and use Maven, you might find this article an interesting read.
 
 
 

What is Gradle?

Gradle introduces themselves as the Enterprise Automation Tool. From what I have seen till now, I tend to agree that it does seem to tick all the boxes for a framework that aims to be that. However, that is a bit of a BHAG, salesy talk. It is a good goal to have (as in, trying to be the Enterprise Automation Tool) but personally I think it is an ambition rather than a reality at the moment.

Stripping ambition and sales pitch – from a java technocrat perspective – Gradle (looks like) fast becoming a good tool to handle all build and release related activities for java projects.

Why should I bother now? Maven works perfectly fine for me.

Yes, it does. I work with some pretty big enterprises, and truth be told, even if they get all their java projects on Maven, they would have made a great stride forward. So, for all practical purposes – per my experience – in a regular corporate enterprise – Maven is not only good enough, but a big leap forward, if correctly and extensively used.

Having said that, while enterprises have the luxury (and indeed also the need) to play safe with tools and technologies, it is not a luxury that we technocrats have. When a tool / technology / framework proves it’s mettle, the enterprises could go and hire the consultants that know those tools (and sometimes the buzzwords) and those technocrats who have not spent enough effort to keep themselves updated could find themselves scrambling to keep up. The trick is to know which technology to invest time on and which not.

As for Gradle, it has managed to get some really impressive patrons. Spring folks have moved Spring core to Gradle. Hibernate folks documented in detail the reasons for them moving on to Gradle. Grails folks seem to have a strong opinion in favour of Gradle.

I am not going to try and enlist the goodness of Gradle. For one, I don’t know enough about the tool yet. Secondly, the links that I have already shared are from some pretty big names, working with pretty successful technology companies, and they have done quite a good job of putting together the benefits of Gradle.

My simple summary would be

  1. Gradle allows you to code stuff in Groovy. Hence, you could pretty much code whatever you want your build and release script to do.
  2. Gradle – having the chance to learn from it’s forerunners like Maven – seem to have fixed a few problems right at the onset. Handling multiple modules, working with multiple source folders etc would be good examples.
  3. Not being around as long as Maven means that support is a bit sketchy. The
    plugin for STS that I used, definitely had some rough edges.
  4. Since you could code pretty much anything you wanted, it is just as easy to shoot yourself in the foot. Being so flexible – I think would mean a difficult time for enterprises to have a standardized build and release across projects, using Gradle.

So, there you go. Two points in favor and two points against. Pretty balanced. This was enough to get me interested. If you are intrigued as well, pray read on.

Ok. So, how do I start?

I would recommend you start by bookmarking a few links. Gradle home page, download page, list of associated tools. Building and Testing with Gradle, the ebook. It is totally worth the registration. I recommend it. Finally the Gradle User Guide, which you will be able to better comprehend after you have spent some more time with Gradle.

So, go ahead, download the latest version. I have got version 1.3 for this article. Unzip it and put it in whichever location you fancy. I generally dump such tools (java based ones) at C:\ProgramFiles (notice the missing space between Program-?-Files). Hence for this article I have a C:\ProgramFiles\gradle-1.3 folder with all the Gradle goodies that we just downloaded.

We need to tweak the gradle.bat file a bit. Add a JAVA_HOME at the beginning of the batch file. Gradle needs to have access to java installation of the machine. Leave the rest of the file as is.

File: C:\ProgramFiles\gradle-1.3\bin\gradle.bat

SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0_09
...
@if '%DEBUG%' == '' @echo off ...
...

Now, just to test that you have got the right stuff wired together, create a batch file. It is just one line, so you could have just typed it on command prompt. But I tend to put this in batch file as I tend to add more stuff in this later on.

File: C:\ProgramFiles\gradle-1.3\bin\GradleCommands.bat

gradle -v

If you run this batch file you will see Gradle announcing it’s version. If you are with me till now you have vanilla Gradle working on your machine. Congratulations. However, that is not going to be enough for most of your practical purposes. Let’s stack up a bit more on tools.

I don’t use Eclipse anymore. STS has done a very good job indeed and I have been using that for a couple of years now. Fortunately, there is a Gradle plugin for STS as well. The installation procedure is well documented and I will not repeat it here. However the installation procedure fails to convey that it is not really quite as straightforward. I tried it on two different machines and had to go through quite a few hoops before I could get it to work. My advice will be to not try it with your work installation of Eclipse / STS, unless you can afford to have it broken for a couple of hours. Make another instance of STS and work off it. Your perseverance will be paid off by a new Gradle import functionality (and a few others, that we will check later), in STS.

One last thing – before you go further, open up ‘preferences’ in STS and set Gradle to be the C:\ProgramFiles\gradle-1.3 folder. I like to make sure that STS is just running the vanilla Gradle and nothing else. If need be, I can get out of STS and type the same commands on command prompt and be assured of the same result. I like to do things from the editor but despise being locked in. Once that is done, you need a java based project (using Gradle) to import.

How do I create a Gradle based Java project to import in STS?

This is where fun starts. Just create a folder (I will call it gradle001). Put a build.gradle file in it. This is all that is needed for STS now to import it. There is a bit of theory behind what goes into build.gradle. I will not delve into it right now. Let’s just look at the following build.gradle file.

File: /gradle001/build.gradle

apply plugin: 'java'

def localMavenRepo = 'file://D:/mavenrepo'
repositories {
    mavenCentral()
    maven { url= localMavenRepo }
}

sourceCompatibility = 1.7
version = '1.0-SNAPSHOT'
group = 'foo.bar.gradle'

dependencies {
   testCompile 'junit:junit:4.11'
}

Do you see the interesting part now? Although I have not added a single line of comment in the file, can you guess what most of the instructions mean there? Most of you would, I hope. Just so you know, I have been using Maven and the local repository was saved at D:/mavenrepo. Using Gradle I could just reuse that local repository and also use the maven central repository. The way I see it, Gradle could not have been friendlier with Maven and I love Gradle for making effort to make developer’s lives that much easier.

Now, we will fire up the STS (with Gradle) and import ‘a new Gradle project’, where we will import the folder structure that we just created. If everything was alright, you will see the project nicely sitting in your ‘project explorer’ view of STS. My personal experience was a bit sketchy on this. I had to try it a couple of times before I got it to work. But once the import was successful, things were much smoother.

But this project does not having anything. Maven used to give me more complete project with a dummy main class and a test class.

Yes. Maven used to ‘create’ a project for you and you could choose from any of the many templates (archetypes) to create your project structure. Alas, I could not find a similar functionality with Gradle (as I admitted right at the beginning of this article, I am new to this tool and hence if I am missing something please let me know. Leave a comment please).

It is a fact that there is no dummy project created for you. However the strength of the tool i.e Gradle is not that. We have already seen how easy it was to read build.gradle. Now let’s write some dummy code and see for ourselves what Gradle can do for us.

File: /gradle001/src/main/java/foo/bar/AppMain.java

package foo.bar;

public class AppMain {
 public static void main(String[] args) {
  System.out.println(new AppMain().greet());
 }
 public String greet() {
  return 'Hello world.';
 }
}

File: /gradle001/src/test/java/foo/bar/AppMainTest.java

package foo.bar;

import static org.junit.Assert.*;

import org.junit.Test;

public class AppMainTest {

 @Test
 public void test() {
  assertEquals(new AppMain().greet(), 'Hello world.'); 
 }

}

Updated File: /gradle001/build.gradle

apply plugin: 'java'

def localMavenRepo = 'file://D:/mavenrepo'
repositories {
 mavenCentral()
 maven { url= localMavenRepo }
}

sourceCompatibility = 1.7
version = '1.0-SNAPSHOT'
group = 'foo.bar.gradle'

dependencies { testCompile 'junit:junit:4.11' }

task(runSimple, dependsOn: 'build', type: JavaExec) {
 main = 'foo.bar.AppMain'
 classpath = sourceSets.main.runtimeClasspath
}

That’s all. Now if we run the ‘runSimple’ task of the build.gradle, Gradle will do a awful lot of stuff for us. It will do the standard clean, compile, test, produce a test report (Check out the /gradle001/build/reports/tests/index.html in your machine, assuming you have been coding the stuff as well till now. You will be pleasantly surprised) , build and finally run the main class. All that for around 18 lines of build.gradle. I must say I don’t think that is a bad deal at all.

Oh, but that is 18 lines of code to build around 25 lines of code. What’s the big deal?

You are right. But you are missing the point. Even if it was 25,000 lines of code, these 18 lines of build script would have done just fine. If you are still not convinced, I recommend you to read this article, where a 264 lines build script seems to be doing phenomenally well.

Umm … fine, but Maven ‘might’ have not been much lengthier either?

You might be right. Although people seem to be providing all sorts of arguments and data against that possibility but I don’t think that is the relevant point to discuss.

The fact is pom.xml in Maven is just a configuration file. On a regular day, a regular build and release person does not code anything in Maven. Of course Maven allows you to create all sorts of plugins and they solve ‘most’ of the problem. But, it seems like, that precisely (the ‘most’) is the point of contention. In places where the scenario / requirement falls outside ‘most’ scenarios, Maven is a very difficult thing to work with. And as technology ecosystem is getting increasingly diverse, people are revolting against that shackle.

Personally, I think this is how the story goes. The batch files (xyz.bat) files were wildly powerful but they were a pain (read impossible) to manage. You had to write them differently for different OS. There was no task hierarchy. I don’t know anyone who liked to maintain them for any but the most trivial of projects.

Hence came in Ant. It was also wildly powerful and did a good job with task management. You had targets for almost everything and for those that you did not have you could just code in a batch file and call that from Ant. Where it fell short was the standardization. People used it in all possible sorts of ways in their projects and in most projects, the build scripts became a project by themselves. They were difficult to manage, only a couple of people in the team knew exactly how they worked and none wanted to have to modify them.

This is where Maven scored big time. It catered to ‘most’ requirements like charm, in a consistent fashion. There was a set way to do most of the things. So, build scripts were not a black hole anymore. And the average Joe was less likely to shoot himself on the foot with Maven scripts.

With Gradle we are flirting with greater power. The average developer would be expected to code with Gradle and not only configure plugins (as in Maven). So, the average developer will have a easier time getting the job done as he / she feels fit.

And that is precisely when the project would have taken up a risk of creating a build script that could potentially do deep damage, have no knowledge base around it, developers will love coding in it but hate maintaining it, managers will have nightmares about build script failing on the day before demo and will have to live with it.

That does not sound very encouraging. What exactly are you saying then?

From what I have seen of Maven – and people seem to agree with me, whether or not they prefer Gradle – it does a good job for standard / average / most requirements. It does what it does extremely well. And there are boundaries that it does not allow you to breach, where it could be seen both as a shackle as well as a safety feature. If you are creating another J2EE web application / java desktop application with standard tech stack, I would say there is no reason to ditch Maven. If you have not embraced it yet, please do, your life will be much easier.

However, if you are in a product development project and you are pushing the boundaries of what java / j2ee have been perceived to be capable of (and assuming you have not hired only average Joes) I think you might want to have a go at Gradle. It is really capable. It is fun to work with. I think the road ahead for Gradle is really bright and full of possibilities. It is a good thing to invest time on.

That is all for today.

If you have read till now hopefully you have liked this or at least found it engaging. My article is based solely on my tinkering with Gradle and that is not the last word on this topic by any stretch of imagination. If you find anything that is wrong – or right in this article, please leave a comment below. I will be much obliged.
 

Reference: Gradle – A Maven perspective from our JCG partner Partho at the Tech for Enterprise blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

2 Responses to "Gradle – A Maven perspective"

  1. Hans Dockter says:

    You are saying: ‘With Gradle we are flirting with greater power. The average developer would be expected to code with Gradle and not only configure plugins (as in Maven). So, the average developer will have a easier time getting the job done as he / she feels fit.’

    The opposite is the case with Gradle as it push declarativeness even further than Maven. I reccommend to have a look at the first 20 minutes of the following presentation to see how Gradle does that: http://marakana.com/s/post/1288/gradle_open_source_hans_dockter_video

  2. Peter Niederwieser says:

    Nice article. Here is a slightly simplified/more idiomatic version of the build script:


    apply plugin: 'java'

    repositories {
    mavenCentral()
    mavenLocal() // only useful/necessary when exchanging artifacts with other (Maven) builds
    }

    sourceCompatibility = 1.7 // defaults to Java version that Gradle is executed with
    version = '1.0-SNAPSHOT'
    group = 'foo.bar.gradle'

    dependencies { testCompile 'junit:junit:4.11' }

    // doesn't have to depend on whole `build`
    // can figure out its task dependencies automatically
    task runSimple(type: JavaExec) {
    main = 'foo.bar.AppMain'
    classpath = sourceSets.main.runtimeClasspath
    }

Leave a Reply


7 − three =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books