Channels ▼
RSS

JVM Languages

Writing Build Scripts With Gradle


Listing Available Tasks of a Project

In the previous section, I explained how to run a specific task using the gradle command. Running a task requires you to know the exact name. Wouldn't it be great if Gradle could tell you which tasks are available without you having to look at the source code? Gradle provides a helper task named tasks to introspect your build script and display each available task, including a descriptive message of its purpose. Running gradle tasks in quiet mode produces the following output:

$ gradle -q tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
setupBuild - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Help tasks
----------
dependencies - Displays the dependencies of root project 'grouptherapy'.
dependencyInsight - Displays the insight into a specific dependency in root
 project 'grouptherapy'.
help - Displays a help message
projects - Displays the sub-projects of root project 'grouptherapy'.
properties - Displays the properties of root project 'grouptherapy'.
tasks - Displays the tasks runnable from root project 'grouptherapy' (some of
 the displayed tasks may belong to subprojects).
Other tasks
-----------
groupTherapy
To see all tasks and more detail, run with --all.

There are some things to note about the output. Gradle provides the concept of a task group, which can be seen as a cluster of tasks assigned to that group. Out of the box, each build script exposes the task group Help tasks without any additional work from the developer. If a task doesn't belong to a task group, it's displayed under Other tasks. This is where you find the task groupTherapy.

You may wonder what happened to the other tasks that you defined in your build script. On the bottom of the output, you'll find a note that you can get even more details about your project's tasks by using the --all option. Run it to get more information on them:

  $ gradle -q tasks --all
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
setupBuild - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Help tasks
----------
dependencies - Displays the dependencies of root project 'grouptherapy'.
help - Displays a help message
projects - Displays the sub-projects of root project 'grouptherapy'.
properties - Displays the properties of root project 'grouptherapy'.
tasks - Displays the tasks runnable from root project 'grouptherapy' (some of
 the displayed tasks may belong to subprojects).
Other tasks
-----------
groupTherapy
    startSession
    yayGradle0
    yayGradle1
    yayGradle2

The --all option is a great way to determine the execution order of a task graph before actually executing it. To reduce the noise, Gradle is smart enough to hide tasks that act as dependencies to a root task. For better readability, dependent tasks are displayed indented and ordered underneath the root task.

Task Execution

In the previous examples, we told Gradle to execute one specific task by adding it as an argument to the command gradle. Gradle's command-line implementation will in turn make sure that the task and all its dependencies are executed. You can also execute multiple tasks in a single build run by defining them as command-line parameters. Running gradle yayGradle0 groupTherapy would execute the task yayGradle0 first and the task groupTherapy second.

Tasks are always executed just once, no matter whether they're specified on the command line or act as a dependency for another task. Let's see what the output looks like:

$ gradle yayGradle0 groupTherapy
:startSession
[ant:echo] Repeat after me...
:yayGradle0
Gradle rocks
:yayGradle1
Gradle rocks
:yayGradle2
Gradle rocks
:groupTherapy

No surprises here. You see the same output as if you'd just run gradle groupTherapy. The correct order was preserved and each of the tasks was only executed once.

Task Name Abbreviation

One of Gradle's productivity tools is the ability to abbreviate camel-cased task names on the command line. If you wanted to run the previous example in the abbreviated form, you'd just need to type gradle yG0 gT. This is especially useful if you're dealing with very long task names or multiple task arguments. Keep in mind that the task name abbreviation has to be unique to enable Gradle to identify the corresponding task. Consider the following scenario:

task groupTherapy << {
   ...
}

task generateTests << {
   ...
}

Using the abbreviation gT in a build that defines the tasks groupTherapy and generate-Tests causes Gradle to display an error:

$ gradle yG0 gT

FAILURE: Could not determine which tasks to execute.

* What went wrong:
Task 'gT' is ambiguous in root project 'grouptherapy'. Candidates are:
  'generateTests', 'groupTherapy'.

* Try:
Run gradle tasks to get a list of available tasks.

BUILD FAILED

Excluding a Task from Execution

Sometimes you want to exclude a specific task from your build run. Gradle provides the command-line option –x to achieve that. Let's say you want to exclude the task yayGradle0:

$ gradle groupTherapy -x yayGradle0
:yayGradle1
Gradle rocks
:yayGradle2
Gradle rocks
:groupTherapy

Gradle excluded the task yayGradle0 and its dependent task startSession, a concept Gradle calls smart exclusion. Now that you're familiar with the command line, let's explore some other helpful functions.

Command-line Options

In this section, I explore the most important general-purpose options, flags to control your build script's logging level, and ways to provide properties to your project. The gradle command allows you to define one or more options at the same time. Let's say you want to change the log level to INFO using the –i option and print out any stack trace if an error occurs during execution with the option -s. To do so, execute the task groupTherapy command like this: gradle groupTherapy–is or gradle groupTherapy -i -s. As you can see, it's easy to combine multiple options. To discover the full set, run your build with the –h argument. I won't go over all the available options, but the most important ones are:

  • -?, -h, --help: Prints out all available command-line options including a descriptive message.
  • -b, --build-file: The default naming convention for Gradle build script is build.gradle. Use this option to execute a build script with a different name (for example, gradle –b test.gradle).
  • --offline: Often your build declares dependencies on libraries only available in repositories outside of your network. If these dependencies were not stored in your local cache yet, running a build without a network connection to these repositories would result in a failed build. Use this option to run your build in offline mode and only check the local dependency cache for dependencies.
  • -D, --system-prop: Gradle runs as a JVM process. As with all Java processes, you can provide a system property like this: –Dmyprop=myvalue.
  • -P, --project-prop: Project properties are variables available in your build script. You can use this option to pass a property to the build script directly from the command line (for example, -Pmyprop=myvalue).
  • -i, --info: In the default settings, a Gradle build doesn't output a lot of information. Use this option to get more informative messages by changing Gradle's logger to INFO log level. This is helpful if you want to get more information on what's happening under the hood.
  • -s, --stacktrace: If you run into errors in your build, you'll want to know where they stem from. The option –s prints out an abbreviated stack trace if an exception is thrown, making it perfect for debugging broken builds.
  • -q, --quiet: Reduces the log messages of a build run to error messages only.
  • tasks: Displays all runnable tasks of your project including their descriptions. Plugins applied to your project may provide additional tasks.
  • properties: Emits a list of all available properties in your project. Some of these properties are provided by Gradle's project object, the build's internal representation. Other properties are user-defined properties originating from a property file or property command-line option, or directly declared in your build script.

Gradle Daemon

When using Gradle on a day-to-day basis, you'll find yourself running your build repetitively. This is especially true if you're working on a Web application. You change a class, rebuild the Web application archive, bring up the server, and reload the URL in the browser to see your changes being reflected. Many developers prefer test-driven development to implement their application. For continuous feedback on their code quality, they run their unit tests over and over to find code defects early on. In both cases, you'll notice a significant productivity hit. Each time you initiate a build, the JVM has to be started, Gradle's dependencies have to be loaded into the class loader, and the project object model has to be constructed. This procedure usually takes a couple of seconds. The Gradle daemon can help here.

The daemon runs Gradle as a background process. Once started, the gradle command will reuse the forked daemon process for subsequent builds, avoiding the startup costs altogether. Let's go back to the previous build script example. On my machine, it takes about three seconds to successfully complete running the task groupTherapy. Let's try to improve the startup and execution time. It's easy to start the Gradle daemon on the command line: simply add the option --daemon to your gradle command. You may notice that we add a little extra time for starting up the daemon as well. To verify that the daemon process is running, you can check the process list on your operating system:

  • Mac OS X and *nix: In a shell run the command ps | grep gradle to list the processes that contain the name gradle.
  • Windows: Open the task manager with the keyboard shortcut Ctrl+Shift+Esc and click the Processes tab.

Subsequent invocations of the gradle command will now reuse the daemon process. Give it a shot and try running gradle groupTherapy --daemon. You'll find you got the startup and execution time down to about one second! Keep in mind that a daemon process will only be forked once even though you add the command-line option --daemon. The daemon process will automatically expire after a three-hour idle time. At any time you can choose to execute your build without using the daemon by adding the command-line option --no-daemon. To stop the daemon process, manually run gradle --stop. That's the Gradle daemon in a nutshell. For a deep dive into all configuration options and intricacies, refer to the Gradle online documentation.

Conclusion

Existing tools can't meet the build needs of today's industry. Improving on the best ideas of its competitors, Gradle provides a build-by-convention approach, reliable dependency management, and support for multi-project builds without having to sacrifice the flexibility and descriptiveness of your build.

In this series, we explored how Gradle can be used to deliver in each of the phases of a deployment pipeline in the context of continuous delivery. We ran some simple build scripts and 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. As you explore Gradle further, I'm quite sure you'll conclude it's an important step forward for building Java projects. Enjoy!


Benjamin Muschko is the author of Gradle in Action, published by Manning, from which this article is excerpted and adapted with permission. A special discount code has been set up for Dr. Dobb's readers for this book. Use ddgrad for a 42% discount off retail price (in all formats).

Related Article

Why Build Your Java Projects with Gradle Rather than Ant or Maven?


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video