With the release of Asciidoctor 2.0.0 we get nice help on the basic syntax of Asciidoc with the command-line option --help syntax
.
This gives us samples of the syntax in Asciidoc markup.
As mentioned by Dan Allen on Twitter we can pipe the syntax sample to Asciidoctor itself to get a HTML page:
Continue reading →
Micronaut can convert String values defined as a number followed by (case-insensitive) KB/MB/GB
to a number value in certain cases.
The conversion service in Micronaut supports the @ReadableBytes
annotation that we can apply to a method parameter.
Micronaut will then parse the String value and convert it to a number.
The value 1Kb
is converted to 1024
.
We can use this for example in a configuration class or path variable in a controller.
Continue reading →
Micronaut supports the RFC-6570 URI template specification to define URI variables in a path definition.
The path definition can be a value of the @Controller
annotation or any of the routing annotations for example @Get
or @Post
.
We can define a path variable as {?binding*}
to support binding of request parameters to all properties of an object type that is defined as method argument with the name binding
.
We can even use the Bean Validation API (JSR380) to validate the values of the request parameters if we add an implementation of this API to our class path.
Continue reading →
Working with SQL database from Groovy code is very easy using the groovy.sql.Sql
class. The class has several methods to execute a SQL query, but we have to take special care if we use methods from Sql
that take a GString
argument. Groovy will extract all variable expressions and use them as values for placeholders in a PreparedStatement
constructed from the SQL query. If we have variable expressions that should not be extracted as parameters for a PreparedStatement
we must use the Sql.expand
method. This method will make the variable expression a groovy.sql.ExpandedVariable
object. This object is not used as parameter for a PreparedStatement
query, but the value is evaluated as GString
variable expression.
Continue reading →
Spring Boot 2.1 introduced log groups. A log group is a logical name for one or more loggers. We can define log groups in our application configuration. Then we can set the log level for a group, so all loggers in the group will get the same log level. This can be very useful to change a log level for multiple loggers that belong together with one setting. Spring Boot already provides two log groups by default: web and sql. In the following list we see which loggers are part of the default log groups:
- web
-
org.springframework.core.codec
, org.springframework.http
, org.springframework.web
, org.springframework.boot.actuate.endpoint.web
, org.springframework.boot.web.servlet.ServletContextInitializerBeans
- sql
-
org.springframework.jdbc.core
, org.hibernate.SQL
Continue reading →
To get an overview of all Gradle tasks in our project we need to run the tasks
task. Since Gradle 5.1 we can use the --group
option followed by a group name. Gradle will then show all tasks belonging to the group and not the other tasks in the project.
Suppose we have a Gradle Java project and want to show the tasks that belong to the build group:
Continue reading →
In a previous post we learned how to include parts of a document in the generated output.
The included parts are defined using tags.
The start of a tag is defined in a comment with the format tag::_tagName_[]
and the end has the format end::_tagName_[]
.
Next we must use the tags
attribute for the include
macro followed by the tagName.
If we don’t want to include a tag we must prefix it with an exclamation mark (!
).
Continue reading →
Since Java 9 we can specify that the Javadoc output must be generated in HTML 5 instead of the default HTML 4. We need to pass the option -html5
to the javadoc
tool. To do this in Gradle we must add the option to the javadoc
task configuration. We use the addBooleanOption
method of the options
property that is part of the javadoc
task. We set the argument to html5
and the value to true
.
In the following example we reconfigure the javadoc
task to make sure the generated Javadoc output is in HTML 5:
Continue reading →
One of the most important features in Gradle is the support for incremental tasks. Incremental tasks have input and output properties that can be checked by Gradle. When the values of the properties haven’t changed then the task can be marked as up to date by Gradle and it is not executed. This makes a build much faster. Input and output properties can be files, directories or plain object values. We can set a task input property with a date or date/time value to define when a task is up to date for a specific period. As long as the value of the input property hasn’t changed (and of course also the other input and output property values) Gradle will not rerun task and mark it as up to date. This is useful for example if a long running task (e.g. large integration test suite) only needs to run once a day or another period.
In the following example Gradle build file we define a new task Broadcast
that will get content from a remote URL and save it in a file. In our case we want to save the latest messages from SDKMAN!. If you don’t know SKDMAN! you should check it out!. The Broadcast
task has an incremental task output property, which is the output file of the task:
Continue reading →
In Micronaut we can inject configuration properties in different ways into our beans. We can use for example the @Value
annotation using a string value with a placeholder for the configuration property name. If we don’t want to use a placeholder we can also use the @Property
annotation and set the name
attribute to the configuration property name. We have to pay attention to the format of the configuration property name we use. If we refer to a configuration property name using @Value
or @Property
we must use lowercased and hyphen separated names (also known as kebab casing). Even if the name of the configuration property is camel cased in the configuration file. For example if we have a configuration property sample.theAnswer
in our application.properties
file, we must use the name sample.the-answer
to get the value.
In the following Spock specification we see how to use it in code. The specification defines two beans that use the @Value
and @Property
annotations and we see that we need to use kebab casing for the configuration property names, even though we use camel casing to set the configuration property values:
Continue reading →
Normally we would consume server-sent events (SSE) in a web browser, but we can also consume them in our code on the server. Micronaut has a low-level HTTP client with a SseClient
interface that we can use to get server-sent events. The interface has an eventStream
method with different arguments that return a Publisher
type of the Reactive Streams API. We can use the RxSseClient
interface to get back RxJava2 Flowable
return type instead of Publisher
type. We can also use Micronaut’s declarative HTTP client, which we define using the @Client
annotation, that supports server-sent events with the correct annotation attributes.
In our example we first create a controller in Micronaut to send out server-sent events. We must create method that returns a Publisher
type with Event
objects. These Event
objects can contains some attributes like id
and name
, but also the actual object we want to send:
Continue reading →
We can add Micronaut beans to the application context of a Spring application.
Micronaut has a MicronautBeanProcessor
class that we need to register as Spring bean in the Spring application context.
We can define which Micronaut bean types need to be added to the Spring application context via the constructor of the MicronautBeanProcessor
class.
This way we can use Micronaut from inside a Spring application.
For example we can use the declarative HTTP client of Micronaut in our Spring applications.
First we need to add dependencies on Micronaut to our Spring application.
In this example we will use the Micronaut HTTP client in our Spring application and use Gradle as build tool.
We must add the following dependencies:
Continue reading →