We were promised that microservices would make our software more stable and easier to scale horizontally. But the added complexity often creates a lot of shared code and complex infrastructure.
Dapr promises a solution by placing these cross-cutting concerns outside your code.
Continue reading →
Kotlin’s standard library offers many functions, but the ones that stand out in my opinion are scope functions. These scope functions
exist to execute a code block in the context of the object on which you execute it. Within this scope, you can perform operations on the object with or without a name. Scope functions can make code more readable and concise, but beware! Nesting scope functions can cause confusion about the current context object.
Continue reading →
When using mutual TLS (mTLS), the client authenticates the server by checking whether the server’s certificate is signed with a trusted CA certificate, i.e. a certificate that exists in its trust store.
And vice versa, the server authenticates the client by checking the client’s certificate against its truststore.
Both authentications are done at TLS level.
Mutual TLS thus requires truststores and keystores on both the client and server side.
One-way TLS only requires a keystore on the server side, and a truststore on the client side.
So one-way TLS requires a simpler client setup, because it does not need a client specific keystore.
But how does authentication work with own-way TLS. Specifically, how does one protect againts a man-in-the-middle attack?
Continue reading →
In Groovy we can apply the @NullCheck
annotation to a class, constructor or method. The annotation is an AST (Abstract Syntax Tree) transformation and will insert code that checks for null values in methods or constructors. If a null
value is passed to an annotated method or constructor, it will throw an IllegalArgumentException
. Without the annotation we could have a NullPointerException
if we try to invoke a method on the value we pass as argument. The annotation has an optional property includeGenerated
which by default is false
. If we set it to true
then the null checks are also applied to generated methods and constructors. This is very useful if we apply other AST transformations to our class that generates additional code.
Continue reading →
You never touched Groovy, nor did you jump on the Scala train.
Clojure never attracted you; and you heard about Ceylon long after the language had already died.
You are one of those old-fashioned Java folks!
But now, after all those years, you want to join the cool Kotlin kids.
So, where to start?
Let’s discover the language together by decompiling it to Java code.
Today: Inline functions caveats!
Continue reading →
Within software engineering, innovation is the name of the game.
Like I discussed in my previous blog post, we are continually searching for ways to optimize work, boost productivity, and deliver value to users more efficiently.
As we explore prompt engineering in the context of software development, a crucial question arises: Is it a complementary tool enhancing our software engineering arsenal, or does it pose a fundamental challenge to traditional software engineering practices?
Continue reading →
It were 2 intensive days full of collaboration with people inspired by Domain Driven Design and Event Driven systems. Please, read on for my key takeaways.
Continue reading →
The Gradle Java plugin extends the Base plugin and provides the tasks needed to build a Java (or Kotlin) project.
They resemble the Maven build phases for those familiar with Maven.
See also Migrating Builds From Apache Maven - Understanding the build lifecycle
However, the output from Gradle generally is very different than that of Maven, usually more concise.
This is not always what you want.
Below you will find some nice commands, options, and configurations that can make the output to the console more complete (a bit more like Maven).
This can be particularly helpful when building in a pipeline (eg. GitLab, GitHub, etc.), in which case log files and build reports are usually less or not available.
Most of the time all you have is the output to standard out, in which case you would like it to be as complete as possible, specially when the build fails.
Continue reading →
The assertion error messages from AssertJ will use the toString()
method of an object to give more insight about why the assertion could have failed. If an object doesn’t override the toString()
method the default implementation is Object#toString()
. The default implementation will print out the class name and an hexadecimal value of hashCode
separated by a @
. This doesn’t give much information about the actual object. For classes we have control over we can always implement a toString()
method, but for third party classes we may not be able to do that. In order to customize how an object is represented in assertion error messages, AssertJ allows us to provide a custom representation class for an object. The custom representation class must implement the org.assertj.core.presentation.Representation
interface. The interface has one method String toStringOf(Object)
that should return a String representation of the object. If we want to keep the default behavior for other classes and only override it for our own class, we can extend the StandardRepresentation
class and override the method String fallbackToStringOf(Object)
.
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 →