Gradle build-tool cookbook
Contents
Gradle build-tool cookbook¶
Working on OSX, I installed gradle from brew
brew install gradle
which uses openjdk
as the dependency, since I don’t believe I installed any updated JDK previously (like oracle). It also provides this warning
openjdk is keg-only, which means it was not symlinked into /usr/local,
because it shadows the macOS `java` wrapper.
If you need to have openjdk first in your PATH run:
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk you may need to set:
export CPPFLAGS="-I/usr/local/opt/openjdk/include"
Subsequently did I install the Oracle JDK 14 (openjdk is 13 in keg) so caution when assuming the JDK.
Table of Contents¶
Gradle configuration¶
Changing the JDK used by gradle can be done in two ways
In
gradle.properties
in the.gradle
directory in home directory, set
org.gradle.java.home = '/[path_to_jdk_directory]'
or
In
build.gradle
, add
compileJava.options.fork = true
compileJava.options.forkOptions.executable = '/[path_to_javac]'
The second option I would imagine is system dependent (haven’t tried).
A worked example¶
This example follows the spring.io tutorial.
We set up a directory structure mkdir -p src/main/java/hello/
, where we have two classes defined: HelloWorld.java
and Greeter.java
, both in the hello
package. HelloWorld
implements an instance of Greeter
.
Gradle can be started by typing gradle
in a terminal, which defaults to print the help message. Gradle manages different tasks, which for any project can be listed using
gradle tasks
The tasks utilize a build.gradle
file which defines their behaviour and integration into the project. Different plugins can extend the possible tasks gradle can undertake, so it is worth listing them periodically.
For most barebones build.gradle
file we can write contains a single plugin
apply plugin: 'java'
and is located in the root project folder, along side src
.
We can run this using
gradle build
which creates a build
directory. Gradle understands the project structure, so already has compiled our .java
files into .class
files, and created a MANIFEST.MF
file. It also creates a .jar
named after the project folder.
Dependencies are stored in the dependency_cache
, which at this point should be empty, as we do not specify any dependencies in the build file.
The output of the command also includes unit test executions, of which there are none, since none have been defined.
Using joda.time
and declaring dependencies¶
SupposeHelloWorld.java
used the joda.time
library. We would need to specify in the build file where this library can be found. We add a repository for these external libraries
repositories {
mavenCentral()
}
and declare new dependencies as
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
The syntax follows {group}:{library}:{version}
. We also specified that, e.g., joda-time
should be a compile
dependency, i.e. only available during compile time. testCompile
on the other hand would not be included in build or runtime code, but only used when compiling and execute tests.
Specifying JAR artifact¶
We can provide a simple name and version number for our artifact
jar {
baseName = 'gs-gradle'
version = '0.1.0'
}
This would create an artifact when gradle build
is executed with the name gs-gradle-0.1.0.jar
.
Building the example project with a gradle wrapper¶
The gradle wrapper is batch script in Wnidows, and a shell script in *nix
, allowing gradle builds to be performed even on machines that do not have gradle installed.
To create a wrapper, execute
gradle wrapper --gradle-version 2.13
which creates a few new files, namely the two OS specific build scripts, and a gradle/wrapper/
directory, with the wrapper artifact and properties descriptors.
To build now (install agnostic) run
./gradlew build
The first time the wrapper runs, it will download and cache gradle binaries for the specified version (this also means that even if you have gradle installed, executing the project specific wrapper ensures you have the correct version for this project).
We can inspect the generated artifact with
jar tvf build/libs/gs-gradle-0.1.0.jar
Note that the dependencies are not included here, nor is this .jar
executable. To amend this, we use the application
plugin.
Making the project executable as an application¶
We add a few lines to define the new plugin and the main class in our build file
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
which then allows us to run the application immediately with
./gradlew run
To bundle the dependencies requires a little more work. Suppose we build a WAR file, we could easily use gradle’s WAR plugin to fascilitate this. For spring boot, similarly, there is a spring-boot-gradle-plugin to assist this.
Flushing wrapper cache¶
The gradle cache is located in
~/.gradle/caches/
Deleting indivdual caches removes them from the wrapper cache (avoids issues with bad JDK paths and similar).
To completely flush the cache, run
rm -rf ~/.gradle/caches/
NB: this also wipes dependency cache, so that will have to be redownloaded.