Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing

A sign of a good understanding of a programming language is not whether one is simply knowledgeable about the language’s functionality, but why such functionality exists. Without knowing this “why," the developer runs the risk of using functionality in situations where its use might not be ideal - or even should be avoided in its entirety! The case in point for this article is the lateinit keyword in Kotlin. Its presence in the programming language is more or less a way to resolve what would otherwise be contradictory goals for Kotlin:

  • Maintain compatibility with existing Java code and make it easy to transcribe from Java to Kotlin. If Kotlin were too dissimilar to Java - and if the interaction between Kotlin and Java code bases were too much of a hassle - then adoption of the language might have never taken off.
  • Prevent developers from declaring class members without explicitly declaring their value, either directly or via constructors. In Java, doing so will assign a default value, and this leaves non-primitives - which are assigned a null value - at the risk of provoking a NullPointerException if they are accessed without a value being provided beforehand.

The problem here is this: what happens when it’s impossible to declare a class field’s value immediately? Take, for example, the extension model in the JUnit 5 testing framework. Extensions are a tool for creating reusable code that conducts setup and cleanup actions before and after the execution of each or all tests. Below is an example of an extension whose purpose is to clear out all designated database tables after the execution of each test via a Spring bean that serves as the database interface:

Project Hygiene, Part 2: Combatting Goodhart’s Law and Other “Project Smells”

This is a continuation of the Project Hygiene series about best software project practices that started with this article.

Background

“It works until it doesn’t” is a phrase that sounds like a truism at first glance but can hold a lot of insight in software development. Take, for instance, the very software that gets produced. There is no shortage of jokes and memes about how the “prettiness” of what the end-user sees when running a software application is a mere façade that hides a nightmare of kludges, “temporary” fixes that have become permanent, and other less-than-ideal practices. These get bundled up into a program that works just as far as the developers have planned out; a use case that falls outside of what the application has been designed for could cause the entire rickety code base to fall apart. When a catastrophe of this kind does occur, a post-mortem is usually conducted to find out just how things went so wrong. Maybe it was some black-swan moment that simply never could’ve been predicted (and would be unlikely to occur again in the future), but it’s just as possible that there was some issue within the project that never got treated until it was too late.

Back To The Future: Server-Side Web Pages With Kotlin (Pt. 2)

Recap: Server-Side Web Pages With Kotlin

In the first article, server-side web pages with Kotlin part 1, a brief history of web development was outlined: namely, the four main stages being static HTML page delivery; server-side programmatic creation of web pages; HTML templating engines, again server-side; and finally, client-side programmatic creation of web pages. While contemporary web development is mostly focused on the last of the four stages (i.e., creating web pages on the client side), there still exist good cases for rendering web pages on the server side of the web application; furthermore, new technologies like kotlinx.html – a library by the authors of Kotlin for generating HTML code via a domain-specific language (DSL) – provide additional options for server-side web development. To give an example, the following two approaches produce the same homepage for the Spring Boot-powered website of a hypothetical bookstore:

Templating Engine (Thymeleaf)

The basic workflow for rendering a webpage with a template engine like Thymeleaf is to create an HTML template page in the resources/templates folder of the project, in this case home.html:

Back to the Future: Server-Side Web Pages With Kotlin (Pt. 1)

Web development has undergone a variety of changes since the internet became popularized in the 1990s:

  • First came the most basic of the basic: HTML pages that were completely statically rendered, with no dynamism whatsoever.
  • Later came technologies like the Common Gateway Interface that allowed for generating HTML code for a webpage programmatically.
  • Then came templating engines like JavaServer Pages (now Jakarta Server Pages), ASP.NET, and Thymeleaf that enabled developers to work with template files that were predominantly “HTML-looking” with programming code intermixed.
  • Next came Javascript-based “client-side scripting” frameworks like Angular, React, and Vue, which transformed web development into two separate disciplines: the “backend” development that contained the traditional web server and business logic code along with “front-end” development (using the frameworks above) that would be concerned with a website’s visualization and receive data from the backend.

However, this is not to say that development trends only advance in one direction and never backward. For example, NoSQL databases like MongoDB quickly gained popularity in no small part due to their ability to hold unstructured data compared to traditional SQL databases like PostgreSQL and MySQL, yet those latter databases have evolved as well and can now contain unstructured data via the JSONB and JSON data types, respectively. Likewise, new Javascript frameworks like Next.js are starting to offer options for server-side rendering alongside their now-traditional client-side rendering capabilities. Again, server-side templating engines like Thymeleaf have also continued to evolve, with Thymeleaf releasing a new version of the framework last December.

JSON in Kotlin

In any web service that receives and transmits data to and from a server, the first and last events will usually be transforming the data from the format used by the web request into the format that the web server will handle, and vice versa; these operations are called deserialization and serialization, respectively. For some web services, the thought put towards this part of the flow of data is focused solely on how to configure the serialization mechanism so it works properly. However, there are some scenarios for which every CPU cycle counts, and the faster the serialization mechanism can work, the better. This article will explore the development and performance characteristics of four different options for working with the serialization of JSON messages—GSON, Jackson, JSON-B, and Kotlinx Serialization, using both the Kotlin programming language and some of the unique features that Kotlin offers compared to its counterpart language, Java.

Setup

Since its first release in 2017, Kotlin has grown by leaps and bounds within the JVM community, becoming the go-to programming language for Android development as well as a first-class citizen in major JVM tools like Spring, JUnit, Gradle, and more. Among the innovations it brought to the JVM community compared to Java was the data class, a special type of class that is to be used primarily as a holder of data (in other words, a Data Transfer Object, or DTO) and automatically generates base utility functions for the class like equals(), hashcode(), copy(), and more. This will form the base of the classes that will be used for the performance tests, the first of which being PojoFoo. “Pojo” stands for “Plain Old Java Object,” signifying using only basic class types of the Java programming language:

A Proposal for the Less Conventional

In the list of activities in the Scrum software development life cycle ranked by their popularity amongst developers, “attending meetings” is perhaps locked in a perpetual battle only with “writing documentation” for the position of last place. It’s quite understandable: meetings can easily become very boring — especially when a participant does not have anything to contribute to the meeting at hand — and are often perceived as having little value (if at all) compared to conducting actual code-writing in the software development project. However, these Scrum meetings can and do provide value to the project, even if the members of the team do not perceive it:

  • Sprint refinements enable a product owner and the team to plan out development tasks in the weeks/months to come as well as identify whether any task might need further examination and/or design.
  • Sprint plannings define what work the team should be set to accomplish in the given sprint period.
  • Sprint demos provide visibility to other teams and/or project stakeholders into what a team is working on and has accomplished and permits questioning for clarity regarding the work (or even challenges to ensure that the produced work is robust and has fulfilled all objectives).
  • Sprint retrospectives allow a team to identify factors in the previous sprint that were well-received, could be addressed for improvement or elimination, etc.

This is, of course, merely reciting from the doctrine of Scrum. Whatever benefits these meetings may hope to provide will not appear if the participants of the Scrum meeting are not interested in “playing their part” in said meetings — execution, after all, eats strategy for breakfast. What can be done, then? One could:

Project Hygiene

Overview

  • “Eat your veggies!”
  • “Exercise multiple times a week!”
  • “Brush your teeth and floss daily!”

Such are the exhortations that every child has heard (many times!) and grown to loathe. However, these are not practices designed solely to make one suffer: They are encouragements to help one develop and maintain good hygiene. Dictionary.com defines hygiene as “A condition or practice conducive to the preservation of health, as cleanliness.” As in, “If you do these things consistently, you’ll reduce the chance of bad things happening to your health in the future.“ However much having to keep brushing teeth daily is a pain, having to get the dentist to pull said teeth due to a neglect of this care is going to be much more painful!

This is a concept that can be easily applied to software engineering as well. Software projects have their own maintenance aspects outside of the main code development tasks: documentation, dependency management, deployment, and so on. Supporting these aspects might not be the most exciting or intellectually-stimulating work, but just like human hygiene, such is the nature of supporting a project’s hygiene: a lack of doing so could cause major pain for the developer in the future. Thus, when developing the practices and activities for a software development team, try making it a practice to develop a plan for maintaining the project’s hygiene via regularly scheduled activities that can be incorporated into the project’s development plan.

Project Loom And Kotlin: Some Experiments

The publishing of Java 19 in September 2022 heralded the first public release of the much-awaited Project Loom into the JVM (Java Virtual Machine) ecosystem. A brief description for those who are unaware: Project Loom is an endeavor year in the making by the developers of the Java programming language to enable the use of virtual threads within Java code. Virtual threads are named as such because, although they possess the appearance and behavior of what developers traditionally regard as threads, they are not actual OS (operating system) threads and instead are aggregated together and executed on top of such OS threads.

The primary benefit of this is that OS threads are “heavy” and bound to a relatively-small limit before their memory requirements overwhelm the operating system, whereas virtual threads are “lightweight” and can be used in much higher numbers. While the functionality of Project Loom is still in the preview phase in the Java 19 release—and “full” functionality is not forthcoming until at least the release of Java 21 in 2023 (or even further in the future)—excitement for Project Loom is quite high, and there is already movement underway in major Java ecosystems to accommodate virtual threads to their utmost potential.

Debugging the Perplexing – Don’t Panic!

In the 10+ years, I’ve spent in software development, I’ve formulated a law of debugging: “The perplexity of a software bug and the simplicity of its probable cause are positively correlated”. Put simply, the more confounding and “impossible” a bug appears to be, the likelier it is that the underlying reason for the bug is not some nightmare compiler edge-case or hardware problem, but rather something that’s actually quite simple. Below are two cases that demonstrate the law in action.

Case #1: Python

My go-to example for this used to be an error in a Python project that took almost an entire day to resolve. Below is a (highly simplified) representation of the code in question: