When Maven needs to download artifacts from a remote repository, it logs the progress of the download. This can lead to a lot of noise in the output. Luckily, we can suppress the logging of the download progress. Since Maven 3.6.1. we can use the command-line option --no-transfer-progress
to disable the logging of the download progress. There is also a short version of the option: -ntp
.
Continue reading →
In a previous blog post we learned about the default input sources that are used by Helidon SE. The list of input sources is different based on which artifacts are on the classpath of our application. When we write tests for code in our application that uses the default configuration created by Config.create()
we must take into account that different input sources are used. Also here it is based on the artifacts that are on the classpath. That means that different files with configuration data are loaded, eg. a file application-test.conf
when we have the artifact helidon-config-hocon
and a file application-test.yml
if the artifact helidon-config-yaml
is on the classpath.
Continue reading →
When we use Helidon SE we can use the Config
class to pass configuration properties to our application. The static method create()
creates a default configuration. The Config
class is then configured to support different input sources. This configuration reads configuration properties from the following sources in order:
-
Java system properties,
-
system environment variables,
-
a file on the classpath that has the name application.properties
(based on default config parser that is part of the artifact helidon-config
).
The last input source behaves differently based on which classes that can parse a configuration file are on the classpath of our application. If we use the helidon-config
artifact on the classpath then the configuration file read is application.properties
. To read a JSON formatted configuration file we must add the helidon-config-hocon
artifact to the classpath. The file that is read is application.json
. With the same artifact we can read a HOCON formatted configuration file that is named application.conf
. Finally if we add the helidon-config-yaml
artifact to the classpath we can read a YAML formatted configuration file that is named application.yaml
or application.yml
. Helidon SE will only read one configuration file from the classpath with the following order of preference:
Continue reading →
Helidon SE provides a web server using Java virtual threads. When we configure the web server we can specify a specific port number the server will listen on for incoming request. If we want to use a random port number we must specify the value 0
. Helidon will then start the web server on a random port number that is available on our machine.
Continue reading →
With @ConfigurationProperties
in Spring Boot we can bind configuration properties to Java classes. The class annotated with @ConfigurationProperties
can be injected into other classes and used in our code. We can use the type Duration
to configure properties that express a duration. When we set the value of the property we can use:
-
a long
value with the unit to express milliseconds,
-
a value following the ISO-8601 duration format,
-
a special format supported by Spring Boot with the value and unit.
Continue reading →
The Java Development Kit (JDK) includes a tool called jshell
that can be used to interactively test Java code. Normally we run jshell
and type Java code to be executed from an interactive shell. But we can also use jshell
as a tool on the command line to accept standard input containing Java code to be executed. The output of the code can be used as input for another tool on the command line. We run jshell -
to run jshell
and accept standard input. The simplest way to pass Java code to jshell
is to use echo
to print the Java code to standard output and pipe it to jshell
.
Continue reading →
With @ConfigurationProperties
in Spring Boot we can bind configuration properties to Java classes. The class annotated with @ConfigurationProperties
can be injected into other classes and used in our code. We can use the type DataSize
to configure properties that express a size in bytes. When we set the value of the property we can use a long
value. The size is then in bytes as that is the default unit. We can also add a unit to the value. Valid units are B
for bytes, KB
for kilobytes, MB
for megabytes, GB
for gigabytes and TB
for terabytes.
We can also use the @DataSizeUnit
annotation to specify the unit of the property in our class annotated with @ConfigurationProperties
. In that case a the value without a unit assigned to the property is already in the specified unit.
Continue reading →
AssertJ already provides many useful assertions for all kind of types. But sometimes we want to define our own assertions for our own types. We can define new assertions by extending the AbstractAssert
class In this class we add methods that will check the values of our type. The names of the methods can reflect the domain model of our type. This can make our tests more readable and understandable.
Continue reading →
To compare nested objects we can use the usingRecursiveComparison()
method in AssertJ. We can set up the nested objects with values we expect, invoke a method that would return the actual nested objects, and then use the usingRecursiveComparison()
method to compare the actual nested objects with the expected nested objects. This is a very clean way to compare nested objects. Also when we would add a new property to the nested objects our test would fail as we didn’t use that new property yet for our expected nested objects.
Continue reading →
The is
macro in the clojure.test
namespace can be used to write assertions about the code we want to test. Usually we provide a predicate function as argument to the is
macro. The prediction function will call our code under test and return a boolean value. If the value is true
the assertion passes, if it is false
the assertion fails. But we can also provide a custom assertion function to the is
macro. In the clojure.test
package there are already some customer assertions like thrown?
and instance?
. The assertions are implemented by defining a method for the assert-expr
multimethod that is used by the is
macro. The assert-expr
multimethod is defined in the clojure.test
namespace. In our own code base we can define new methods for the assert-expr
multimethod and provide our own custom assertions. This can be useful to make tests more readable and we can use a language in our tests that is close to the domain or naming we use in our code.
Continue reading →
The clojure.test
namespace has the are
macro that allows us to combine multiple test cases for the code we want to test, without having to write multiple assertions. We can provide multiple values for a function we want to test together with the expected values. Then then macro will expand this to multiple expressions with the is
macro where the real assertion happens. Besides providing the data we must also provide the predicate where we assert our code under test. There is a downside of the are
macro and that is that in case of assertion failures the line numbers in the error message could be off.
Continue reading →
The namespace clojure.pprint
has some useful function to pretty print different data structures. The function print-table
is particularly useful for printing a collection of maps, where each map represents a row in the table, and the keys of the maps represent the column headers. The print-table
function accepts the collection as argument and prints the table to the console (or any writer that is bound to the *out*
var). We can also pass a vector with the keys we want to include in the table. Only the keys we specify are in the output. The order of the keys in the vector we pass as argument is also preserved in the generated output.
Continue reading →