Spring Boot has many options for externalising the configuration of our application. One of the options it to use OS environment variables. We need to follow certain rules to name the environment variable and then Spring Boot will use the value of variable to set a configuration property. The property name must be in uppercase and any dots need to be replaced with underscores. For example the configuration property
sample.message is set with the environment variable
SAMPLE_MESSAGE. This feature can be useful in a continuous integration environment where we can set environment variables or just when developing locally. The nice thing is that this also works when we use the Spring Boot Gradle plugin. The environment variables are passed on to the Java process that the
bootRun task starts.
Gradle introduced the continuous build feature in version 2.5. The feature is still incubating, but we can already use it in our daily development. The continuous build feature means Gradle will not shut down after a task is finished, but keeps running and looks for changes to files to re-run tasks automatically. It applies perfectly for a scenario where we want to re-run the
test task while we write our code. With the continuous build feature we start Gradle once with the
test task and Gradle will automatically recompile source files and run tests if a source file changes.
The nice thing about Gradle is that we can use Java libraries in our build script. This way we can add extra functionality to our build script in an easy way. We must use the
classpath dependency configuration for our build script to include the library. For example we can include the library Grgit, which provides an easy way to interact with Git from Java or Groovy code. This library is also the basis for the Gradle Git plugin.
For Java or Groovy projects we can use the application plugin in Gradle to run and package our application. The plugin adds for example the
startScripts task which creates OS specific scripts to run the project as a JVM application. This task is then used again by the
installDist that installs the application, and
distTar tasks that create a distributable archive of the application. The
startScripts tasks has the properties
windowsScript that are the actual OS specific script files to run the application. We can use these properties to change the contents of the files.
Migrating from Ant to Gradle is very easy with the
importBuild method from
AntBuilder. We only have to add this single line and reference our existing Ant build XML file and all Ant tasks can now be executed as Gradle tasks. We can automatically rename the Ant tasks if we want to avoid task name collisions with Gradle task names. We use a closure argument with the
importBuild method and return the new task names. The existing Ant task name is the first argument of the closure.
If we run a Gradle build and one of the tasks fails, the whole build stops immediately. So we have fast feedback of our build status. If we don’t want to this and want Gradle to execute all tasks, even though some might have failed, we use the command line option
--continue. When we use the
--continue command line option Gradle will execute every task where the dependent tasks are not failing. This is also useful in a multi-module project where we might want to build all projects even though some may have failing tests, so we get a complete overview of failed tests for all modules.
If we use Gradle in a multi-module project we can define project dependencies between modules. Gradle uses the information from the project dependencies to determine which tasks need to be run. For example if module B depends on module A and we want to build module B, Gradle will also build module A for us, because module B depends on it. But if we know for sure that module A is up to date and has not changed, we can also instruct Gradle to skip building module A, when we build module B.
To get the current Gradle version we can use the
gradleVersion property of the
Gradle object. This returns a string value we can use for displaying the values. If we want to compare Gradle versions we can use the
GradleVersion object. With this class we can get the current version, but we can also compare Gradle versions. This can be useful in our build scripts if we have functionality based on a Gradle version.
To define a
Copy task we specify the files we want to copy and to which directory. This definition is a
CopySpec instance. It contains the rules that defines what we want to copy. The archive tasks
Tar also use a
When we create a task of type
Copy we get a task object that implements the
CopySpec interface. We can use all the methods from this interface to extend our recipe for copying tasks. In the following build file we first define the task
website. We use
CopySpec methods to configure the task. Then we define a task
deploy of type
Sync that also implements the
Gradle uses the name
build.gradle as the default name for a build file. If we write our build code in a file
build.gradle then we don’t have to specify the build filename when we run tasks. We can create build files with a different name other than
build.gradle. For example we can define our build logic in a file
sample.gradle. To run the tasks from this build file we can use the command line option
--build-file followed by the file name. But we can also change the project settings and set a new default build file name for our project. With the changed project settings we do not have to use the command line options