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 →
We have come a long way since the introduction of Servlets back in 1999. Back then, implementing and getting to run a Servlet required a lot of development, class overloading, XML configuration and a host of other tasks. It prompted improvements like Java Servlet pages and the subsequent move towards frameworks like the model-view-controller model with Struts that have evolved from framework to framework to where we are today, with powerful frameworks like Spring Boot, Micronaut et al. But the Servlet component has not remained idle through those times.
Continue reading →
A lot of applications seem to either only use runtime exceptions or only use error monads like the Optional for error handling.
In this blog I will try to dive a bit deeper into when to use one over the other (tldr: you probably need both)
Continue reading →
Since Java 16 we can use the method mapMulti(BiConsumer)
of the Stream
API. This method allows us to map each element of the stream to multiple elements. We can also do that with the flatMap(Function)
method, but if we want to map a limited set of elements, mapMulti
is more convenient. Internally a shared stream is used and we don’t have the cost of creating a new stream for each element. Another use case is if the logic to map an element to multiple elements is complex and is hard to implement by returning a stream. Then mapMulti
allows us to write that logic in a BiConsumer
instead of a Function
.
Continue reading →
Pattern matching got quite an update in Java 19 (although it does require turning on experimental features).
Continue reading →