Defining tables in Asciidoctor is very easy. The start and end of the table are defined by |===
.
But if we want to add a new table to a table cell we cannot use the same syntax.
To define a nested table we must replace the |
separator with !
.
So instead of |===
to indicate the table boundaries we use !===
.
Also the cell separators are now !
instead of |
.
Finally we must make sure the table cell or column supports Asciidoc markup, so the table is properly created.
We must configure the cell or column with a
so the nested table is created.
In the following example Asciidoctor markup we have a simple table with a nested table in the second column and row.
Notice we can still apply all table configuration to the nested table as well:
Continue reading →
Gradle has incremental build support to speed up our builds.
This means Gradle checks input and output for a task and if something changed the task is executed, otherwise the task is skipped.
In previous posts we learned how to add incremental build support to our tasks with annotations and inputs
and outputs
property of a task.
When we have a task that has an output file for an input file, like with transformations, we can have a more efficient task using an incremental task action.
With an incremental task action we have extra information on the files that are handled by the task.
We can have different actions based on if an input file is out of date or removed.
This way we can handle only the input files that have changed or removed with incremental builds, instead of all the input files.
To create an incremental task action we must have a task action method (annotated with @TaskAction
) that has a single argument of type IncrementalTaskInputs
.
The IncrementalTaskInputs
class has the method outOfDate
and removed
.
These methods take an action, that can be implemented with a closure, with an instance of InputFileDetails
as argument.
We can get to the input file via this instance and use that for our task logic.
When an input file is out of date, because the file contents has changed or the output file has been removed, the action we defined for the outOfDate
method is invoked.
If the input file is removed the action for the method removed
is invoked.
Continue reading →
Gradle 3.5 introduced the build cache. With the build cache we can reuse task output from builds that can come from different computers.
We can also use the build cache feature for our local builds.
By default the directory to store the cache is located in the Gradle user home directory on our computer (USER_HOME/.gradle/caches/build-cache-1
).
We can change the directory for the local cache via settings.gradle
of our Gradle project.
For example we could configure a directory in our project file structure to be the build cache directory.
Then it is easy to clean the cache, because it is a directory not shared by other Gradle projects.
With the default directory location in the Gradle user home directory the caches of all Gradle projects we run on our computer are stored in a single directory.
And the cache doesn’t shrink and will only grow we might want to have more control of where the cache of a single Gradle project is stored.
This way we can easily clean the cache, because all files of a project are stored in the directory for that project.
In the following example settings.gradle
file we configure our build cache directory to be the directory build-cache
in the root directory of our project where we store our settings.gradle
file:
Continue reading →
Gradle 3.5 introduced the build cache.
With the build cache we can share task output between builds on different computers.
For example the build output from a continuous integration server can be used on a developer’s computer.
To use the build cache feature we use the command-line option --build-cache
.
Instead of using the command-line option --build-cache
we can set the Gradle property org.gradle.caching
with the value true
in the file gradle.properties
of our project.
To set this property for all our projects we set the property in the gradle.properties
file in the Gradle home directory, which is usually at USER_HOME/.gradle/gradle.properties
.
In the following example we set the property org.gradle.caching
in ~/.gradle/gradle.properties
:
Continue reading →
We can use Spring Boot Actuator to add endpoints to our application that can expose information about our application.
For example we can request the /env
endpoint to see which Spring environment properties are available.
Or use /configprops
to see the values of properties defined using @ConfigurationProperties
.
Sensitive information like passwords and keys are replaced with
.
Spring Boot Actuator has a list of properties that have sensitive information and therefore should be replaced with
.
The default list of keys that have their value hidden is defined as password,secret,key,token,.credentials.,vcap_services
.
A value is either what the property name ends with or a regular expression.
We can define our own list of property names from which the values should be hidden or sanitized and replaced with
.
We define the key we want to be hidden using the application properties endpoints.env.keys-to-sanatize
and endpoints.configprops.keys-to-sanatize
.
In the following example Spring application YAML configuration we define new values for keys we want to be sanitized.
Properties in our Spring environment that end with username
or password
should be sanatized.
For properties set via @ConfigurationProperties
we want to hide values for keys that end with port
and key
:
Continue reading →
When we write a feature method in our Spock specification to test our class we might run into long running methods that are invoked.
We can specify a maximum time we want to wait for a method.
If the time spent by the method is more than the maximum time our feature method must fail.
Spock has the @Timeout
annotation to define this.
We can apply the annotation to our specification or to feature methods in the specification.
We specify the timeout value as argument for the @Timeout
annotation.
Seconds are the default time unit that is used.
If we want to specify a different time unit we can use the annotation argument unit
and use constants from java.util.concurrent.TimeUnit
to set a value.
In the following example specification we set a general timeout of 1 second for the whole specification.
For two methods we override this default timeout with their own value and unit:
Continue reading →
To ignore feature methods in our Spock specification we can use the annotation @Ignore
.
Any feature method or specification with this annotation is not invoked when we run a specification.
With the annotation @IgnoreRest
we indicate that feature methods that do not have this annotation must be ignored.
So any method with the annotation is invoked, but the ones without aren’t.
This annotation can only be applied to methods and not to a specification class.
In the next example we have a specification with two feature methods that will be executed and one that is ignored:
Continue reading →
When we want to transform a Promise
value we can use the map
and flatMap
methods.
There are also variants to this methods that will only transform a value when a given predicate is true: mapIf
and flatMapIf
.
We provide a predicate and function to the methods.
If the predicate is true the function is invoked, otherwise the function is not invoked and the promised value is returned as is.
In the following example we have two methods that use the mapIf
and flatMapIf
methods of the Promise
class:
Continue reading →
The Promise
class has a lot of methods.
One of the methods is the time
method.
We can invoke this method an a Promise
instance.
The method creates a Duration
object that we can use inside the method.
The duration is the time taken from when the promise is subscribed to to when the result is available.
The promise value is not changed, so we can add the time
method at any position of a method chain for the Promise
object.
In the following specification we check the duration for a Promise
that is returned by the method generate
of the class Numbers
.
For our example we wait for a number of seconds dependent on the argument of the generate
method.
In the specification we use the time
method and check the time spent to fulfil the promise.
Continue reading →
To run external Groovy scripts in our Java or Groovy application is easy to do.
For example we can use GroovyShell
to evaluate Groovy code in our applications.
If our script contains print methods like println
we can redirect the output of these methods.
The Script
class, which is a base class to run script code, has an implementation for the print
, printf
and println
methods.
The implementation of the method is to look for a property out
, either as part of a Script
subclass or in the binding added to a Script
class.
If the property out
is available than all calls to print
, printf
and println
methods are delegated to the object assigned to the out
property.
When we use a PrintWriter
instance we have such an object, but we could also write our own class with an implementation for the print
methods.
Without an assignment to the out
property the fallback is to print on System.out
.
In the following example we have a external script defined with the variable scriptText
, but it could also be a file or other source with the contents of the script we want to run.
We assign our own PrintWriter
that encapsulates a StringWriter
to capture all invocations to the print
methods:
Continue reading →
In a previous post we saw how we can use Spring Boot in a Ratpack application.
But the integration can also be the other way around: using Ratpack in a Spring Boot application.
This way we can use Ratpack’s power to handle requests sent to our Spring Boot application and still use all Spring Boot features in our application.
The easiest way to add Ratpack to a Spring Boot application is adding a Ratpack dependency and use the @EnableRatpack
annotation.
With this annotation a RatpackServer
instance is created and started along with configuration options.
Let’s see an example Spring Boot application with Ratpack enabled.
First we add Ratpack as dependency to our Spring Boot application.
In our example we also add Ratpack’s Dropwizard module as dependency. We use Gradle in our example:
Continue reading →
When we start a Spring Boot application and pass arguments to the application, Spring Boot will capture those arguments and creates a Spring bean of type ApplicationArguments
and puts it in the application context.
We can use this Spring bean to access the arguments passed to the application.
We could for example auto wire the bean in another bean and use the provided argument values.
The ApplicationArguments
interface has methods to get arguments values that are options and plain argument values.
An option argument is prefixed with --
, for example --format=xml
is a valid option argument.
If the argument value is not prefixed with --
it is a plain argument.
In the following example application we have a Spring Boot application with a Spring bean that implements CommandLineRunner
.
When we define the CommandLineRunner
implementation we use the ApplicationArguments
bean that is filled by Spring Boot:
Continue reading →