Chapter 2. Next-generation builds with Gradle

 

This chapter covers

  • Understanding how Gradle compares to other build tools
  • Describing Gradle’s compelling feature set
  • Installing Gradle
  • Writing and executing a simple Gradle script
  • Running Gradle on the command line

For years, builds had the simple requirements of compiling and packaging software. But the landscape of modern software development has changed, and so have the needs for build automation.

Today, projects involve large and diverse software stacks, incorporate multiple programming languages, and apply a broad spectrum of testing strategies. With the rise of agile practices, builds have to support early integration of code as well as frequent and easy delivery to test and production environments.

Established build tools continuously fall short in meeting these goals in a simple but customizable fashion. How many times have your eyes glazed over while looking at XML to figure out how a build works? And why can’t it be easier to add custom logic to your build? All too often, when adding on to a build script, you can’t shake the feeling of implementing a workaround or hack. I feel your pain. There has to be a better way of doing these things in an expressive and maintainable way. There is—it’s called Gradle.

2.1. Why Gradle? Why now?

Let’s say you want to copy a file to a specific location under the condition that you’re building the release version of your project. To identify the version, you check a string in the metadata describing your project. If it matches a specific numbering scheme (for example, 1.0-RELEASE), you copy the file from point A to point B. From an outside perspective, this may sound like a trivial task. If you have to rely on XML, the build language of many traditional tools, expressing this simple logic becomes a nightmare. The build tool’s response is to add scripting functionality through nonstandard extension mechanisms. You end up mixing scripting code with XML or invoking external scripts from your build logic. It’s easy to imagine that you’ll need to add more and more custom code over time. As a result, you inevitably introduce accidental complexity, and maintainability goes out the window. Wouldn’t it make sense to use an expressive language to define your build logic in the first place?

Here’s another example. Maven follows the paradigm of convention over configuration by introducing a standardized project layout and build lifecycle for Java projects. That’s a great approach if you want to ensure a unified application structure for a greenfield project—a project that lacks any constraints imposed by prior work. However, you may be the lucky one who needs to work on one of the many legacy projects that follow different conventions. One of the conventions Maven is very strict about is that one project needs to produce one artifact, such as a JAR file. But how do you create two different JAR files from one source tree without having to change your project structure? Just for this purpose, you’d have to create two separate projects. Again, even though you can make this happen with a workaround, you can’t shake off the feeling that your build process will need to adapt to the tool, not the tool to your build process.

2.2. Gradle’s compelling feature set

Let’s take a closer look at what sets Gradle apart from its competitors: its compelling feature set (see figure 2.3). To summarize, Gradle is an enterprise-ready build system, powered by a declarative and expressive Groovy DSL. It combines flexibility and effortless extendibility with the idea of convention over configuration and support for traditional dependency management. Backed by a professional services company (Gradleware) and strong community involvement, Gradle is becoming the number-one choice build solution for many open source projects and enterprises.

2.3. The bigger picture: continuous delivery

There are many benefits to automating the whole process. First and foremost, delivering software manually is slow, error-prone, and nerve-wracking. I’m sure every one of us hates the long nights due to a deployment gone wrong. With the rise of agile methodologies, development teams are able to deliver software faster. Release cycles of two or three weeks have become the norm. Some organizations like Etsy and Flickr even ship code to production several times a day! Optimally, you want to be able to release software by selecting the target environment simply by pressing a button. Practices like automated testing, CI, and deployment feed into the general concept of continuous delivery.

In this book, we’ll look at how Gradle can help get your project from build to deployment. It’ll enable you to automate many of the tasks required to implement continuous delivery, be they compiling your source code, deploying a deliverable, or calling external tools that help you with implementing the process. For a deep dive on continuous delivery and all of its aspects, I recommend Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation by Jez Humble and David Farley (Addison Wesley, 2010).

2.4. Installing Gradle

Getting started with Gradle is easy. You can download the distribution directly from the Gradle homepage at http://gradle.org/downloads. As a beginner to the tool, it makes sense to choose the ZIP file that includes the documentation and a wide range of source code examples to explore. Unzip the downloaded file to a directory of your choice. To reference your Gradle runtime in the shell, you’ll need to create the environment variable GRADLE_HOME and add the binaries to your shell’s execution path:

Now that you’re all set, you’ll implement a simple build script with Gradle. Even though most of the popular IDEs provide a Gradle plugin, all you need now is your favorite editor. Chapter 10 will discuss Gradle plugin support for IDEs like IntelliJ, Eclipse, and NetBeans.

2.5. Getting started with Gradle

Let’s set the lofty goal of creating the typical “Hello world!” example in Gradle. First you’ll create a file called build.gradle. Within that script, define a single atomic piece of work. In Gradle’s vocabulary, this is called a task. In this example, the task is called helloWorld. To print the message “Hello world!” make use of Gradle’s lingua franca, Groovy, by adding the println command to the task’s action doLast. The method println is Groovy’s shorter equivalent to Java’s System.out.println:

A feature we’ve talked about before is Gradle’s tight integration with Ant . Because you have full access to Groovy’s language features, you can also print your message in a method named chant(). This method can easily be called from your task. Every script is equipped with a property called ant that grants direct access to Ant tasks. In this example, you print out the message “Repeat after me” using the Ant task echo to start the therapy session.

2.6. Using the Command line

In the previous sections, you executed the tasks helloWorld and groupTherapy on the command line, which is going to be your tool of choice for running most examples throughout this book. Even though using an IDE may seem more convenient to newcomers, a deep understanding of Gradle’s command-line options and helper tasks will make you more efficient and productive in the long run.

2.7. Summary

Next, you got a first taste of Gradle’s powerful features in action. You installed the runtime, wrote a first simple build script, and executed it. By implementing a more complex build script, you found out how easy it is to define task dependencies using Gradle’s DSL. Knowing the mechanics of Gradle’s command line and its options is key to becoming highly productive. Gradle offers a wide variety of command-line switches for changing runtime behavior, passing properties to your project, and changing the logging level. We explored how running Gradle with the daemon can be a huge timesaver if you have to continuously execute tasks, such as during test-driven development.

In chapter 3, I’ll show how to build a full-fledged, web-enabled application with Gradle. Starting out with a simple, standalone Java application, you’ll extend the code base by adding a web component and use Gradle’s in-container web development support to efficiently implement the solution. We won’t stop there. I’m going to show how to enhance your web archive to make it enterprise-ready and make the build transferable across machines without having to install the Gradle runtime.

sitemap