Find file
Fetching contributors…
Cannot retrieve contributors at this time
234 lines (221 sloc) 10.7 KB
Building and Testing with Gradle
by Tim Berglund & Matthew McCullough
Ch. 1 - Hello, Gradle!
> Gradle sits between Ant & Maven in providing conventions to follow but
also allowing extensions or redefinition of conventions when necessary
> Gradle provides options for how to handle build dependencies, ranging
from interfacing with Maven/Ivy repositories to managing dependencies
by hand
> Gradle provides Groovy DSL for expressing build files
> Groovy-based build files allow general-purpose programming within the
build files
> Gradle plugins are used to describe how to do the build through new task
> "Hello world" in Gradle (build.gradle file) contents:
task helloWorld << {
println 'hello, world!'
> execute with $ gradle -q helloWorld
Ch. 2 - Gradle Tasks
> apply plugin: 'java' to build Java files (when following Maven project
structure conventions)
> fundamental unit of a Gradle build activity is the task
> tasks are named collections of build instructions executed while building
> Gradle overloads the << operator to append a code block to the list of
actions that task performs
> code within {} in Groovy is a closure
> a closure without the << operator is a configuration block
> configuration code runs before the execution phase
> there are 3 lifecycle phases in Gradle: initialization, configuration, and
> in the execution phase, tasks are executed in the order required by
dependency relationships
> Gradle creates an internal object model of the build before executing it
> every new task in a Gradle build is defined as a DefaultTask
> DefaultTask has four methods: dependsOn(task), doFirst(closure),
doLast(closure), and onlyIf(closure)
> dependsOn(task) - adds a task dependency, always runs before this task
> can also declare more than one dependency at once, for example:
task twoDependents {
dependsOn << firstDependentTask
dependsOn << secondsDependentTask
> doFirst(closure) - adds executable code in a task's action before other
executable code, subsequent calls append before the previous calls
> multiple calls to doFirst can be written in a single configuration block
> doLast(closure) - same as doFirst, except it appends as the last action
in a block
> remember the << operator is another way of expressing a doLast invocation
> onlyIf(closure) - determine whether a task should be run, for example:
runThisBlock.onlyIf {['production'] == 'true'
> in Groovy the last statement of a closure is the return value even if
no return statement is present
> DefaultTask also has properties: didWork, enabled, path, logger, logging,
description, temporaryDir
> didWork - boolean property set to True/False based on whether the task
completed successfully, not all tasks set this upon completion although
built-in tasks like Compile, Copy, and Delete do set it
> enabled - boolean property for whether a task should run or not. Setting
enabled to false will prevent the task from executing, although dependent
tasks will still run
> path - string property with the fully qualified path of a task. By default,
set to the task's name with a colon prepended, like ':taskName', when a
task is in a top-level build file
> for tasks not in a top-level build file (nested builds or dependent
subprojects), path is ':subProject:echoMyPath'
> logger - internal Gradle logger object (org.slf4j.Logger), with the
following log levels: DEBUG, INFO, LIFECYCLE, WARN, QUIET, ERROR
> logging - property that gives access to current log level (can be read and
written to by the build)
> description - property that adds metadata to a task, meant as human
readable way of understanding a task
> temporaryDir - returns a File object to a temporary directory for this
build file
> Gradle tasks can also have dynamic properties
> There are many task types besides the DefaultTask type
> task types are specified with type: [Type], for example:
task copyFiles(type: Copy) {
from 'from_location'
into 'to_location'
include '**/*.json', '**/*.py'
> Task types enumerated in this book: Copy, Jar, JavaExec
> Copy task type - copies files from one location to another (example see
above), methods: from, into, include
> Jar task type - creates a Jar file, very customizable task type,
destinationDir property in this task type expects a argument
> JavaExec task type - runs a Java class with a main() method
> Custom task types can be created in several ways
> custom task types can be specified in the build file
> custom task types must extend either DefaultTask or one of its descendents
> larger custom tasks should go into a separate script under the buildSrc
directory in the project root, within subdirectories based on the task
package & name -> for example:
Ch. 3 - Ant and Gradle
> Gradle is a superset of Ant
> Gradle brings everything from Ant into the Gradle namespace with
> Gradle ships with a full copy of Ant
> Gradle provides the flexibility of Ant with dependency management style
of Ivy
> Gradle uses a Directed Acyclic Graph (DAG) like Ant for its execution plan
> a task in Gradle is any step in the directed acyclic graph
> a Gradle task most closely compares to an Ant target, not an Ant task
> a Gradle variable compares to an Ant property
> call Ant echo with: ant.echo(message: "hello from Ant")
> use a custom Ant task with the taskdef method
> Ant tasks can codepend on Gradle tasks as long as Gradle is used
for executing the build
> the ant object is a full Groovy AntBuilder, so Groovy can be used
for more any type of Ant build structure
Ch. 4 - Maven and Gradle
> Gradle aims to take the best of Maven and leave behind what did not work
> Polyglot Maven is not equivalent to Gradle because it retains the legacy
parts of Maven and only removes the XML configuration
> Gradle retains the concept of convention over configuration of Maven but
alters some conventions
> Gradle does not demand the remote repositories of Maven and Ivy
> Gradle removes the XML configuration language of Maven and instead uses
Groovy and a Groovy-based DSL
> Gradle also removes the strict Maven lifecycle and Ant's absence of a
> from the command line enter 'gradle tasks' to see what tasks can be run
> Maven -> Gradle mapping of terms: groupId = group, artifactId = name,
version = version
> each of the above fields is known as a property in Gradle
> from the command line, enter 'gradle properties' to see what properties
are available to Gradle and their defaults or current values
> each plugin introduces new properties that can be listed with
gradle properties
> Gradle offers both an Ivy and Maven dependency and repository compatibility
> libraries are declared as external dependencies in a one-line listing inside
the dependencies closure
> the dependencies closure can also have a field-by-field list with phrases
that represent scopes (configurations) for the external dependencies
> the java plugin contains six available scopes (configurations) for
dependencies: compile, default, testCompile, testRuntime, archives, runtime
> new scopes can be introduced by plugins
> Gradle provides a bridge DSL to use Ivy and Maven structured repositories
> for dependencies stored in a custom folder, Gradle provides the add() method
and the FileSystemResolver() object
> flat is used to add JARs from a flat subdirectory
> JUnit unit tests can be incorporated into a build with the 'junit'
dependency. For example:
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.8.+'
> sourceSets.main allows for specifying additional source folders beyond the
conventional src/main/java folder
> Gradle has support for default tasks and multiple default tasks
> to publish a Maven pm.xml file for a project use Gradle's Maven plug-in
> the gradle install process is compatible with mvn install because it uses
the Maven Ant tasks created by the Maven team
> maven2gradle is a build script converter under active development that
takes a pom.xml file and exports it to a Gradle build file
> the Gradle-M2Metadata-Plug-in is an attempt to directly import Maven
pom.xml files although the project is a work in progress and not yet
intended for production use
Ch. 5 - Testing with Gradle
> Gradle can be used both for unit testing as well as full pipeline automation
with integration tests and advanced testing frameworks (Spock, Geb, etc)
> JUnit test example:
apply plugin: 'java'
repositories {
dependencies {
testCompile 'junit:junit:4.8.2'
> the JUnit execution results from Gradle produce a nicely formatted test
report with tests that were executed, succeeded, and failed
> Gradle provides a maxParallelForks to govern how many JVMs are spawned
to run JUnit tests in parallel
> the forkEvery setting causes a test-running JVM to close and be replaced
by a new JVM after a certain number of tests are run
> example of the above two settings (used in addition to the JUnit test
example above):
test {
maxParallelForks = 10
forkEvery = 25
> Gradle can also be used with the TestNG and Spock frameworks
Ch. 6 - Multiproject Builds
> Gradle allows the definition of a top-level project and a build file for
each subproject, it also allows for the definition of the build entirely
from a top-level build file
> the settings.gradle file tells Gradle what subdirectories of the root
project contain projects
> each subproject can contain its own settings.gradle file
> a simple way to get set up with multiproject builds is to have a
settings.gradle at the project root and a build.gradle in each
subproject and at the project root
> in the settings.gradle file is an include statement for the subprojects,
when the subprojects are in directories equal to their name, for example:
include 'subproject1', 'subproject2'
> when subprojects have individual build files the example would look
like this:
dependencies {
compile project(':subproject1')
compile project(':subproject2')
> a multiproject build can also be expressed in a single master build
> the third way of structuring a multiproject build is with a hybrid
approach that uses several project-specific build files, where some
configuration is placed in the master and some in the subproject
build files
> multiproject builds are still considered a single graph of projects
in the directed acyclic graph