When bytes
meet Mike

Hi! 👋 I'm Mike, a.k.a @mikemybytes, building distributed systems for fun and living. While I specialize in JVM technologies (mainly Java, Kotlin, Spring), my professional interests go far beyond that. Let me show you what I found interesting!

Mike Kowalski

10 years of software development

#craftsmanship / Jul 12, 2023 / 3 min
The calendar doesn’t lie. A decade of my professional career in software development has just passed. 10 years of experience always felt like a magical and very distant boundary. Am I a better engineer now? Am I a different person? Absolutely! Yet, it didn’t happen overnight. Reviewing these changes is a fascinating exercise. Sometimes I struggle to remember what I had for lunch the day before… But 10 years?! That’s really a lot of time! Yet, I feel it was really worth the effort.
Read the article

Introducing JUnit 5 FormattedSource

#testing / May 3, 2023 / 7 min
Quite some time ago, JUnit’s @CsvAnnotation caught my attention. It turned out so interesting, that I dedicated it a separate blog post and a significant part of a conference talk. It also inspired me to create a new way of writing parameterized tests with JUnit 5. The JUnit 5 FormattedSource library allows defining test case arguments in a human-readable way, following a user-defined format. As a result, it can be used to improve tests readability. Let’s have a look at an example:
Read the article

A simple pattern to keep your business logic together

#craftsmanship / Mar 30, 2023 / 5 min
Keeping our domain (business) logic together is usually a really good idea. It not only makes it easier to reason about the most important part of our code but also increases its cohesion. Yet, decoupling the domain code from all the rest (orchestration, persistence, etc.) can be tricky. In this post, I’d like to share a simple pattern that helps me with that. The amazing Unit Testing Principles, Practices, and Patterns book calls it the CanExecute/Execute pattern.
Read the article

Squashing DB migrations using Testcontainers

#java / Feb 1, 2023 / 8 min
Database migrations are a standard way of dealing with database schema changes, especially in the relational world. No matter which solution we choose (e.g. Flyway or Liquibase in the Java ecosystem), the number of migrations usually grows together with the project itself. An unfortunate side effect is that the test execution time grows as well. An effective way of speeding up our test execution in such cases is to squash (compact) all the existing migrations into a single file. This allows one to set up everything in one take and avoids performing unnecessary operations like creating and updating a table that has been removed completely later.
Read the article

Gazing into a crystal ball - my predictions for 2023

#java / Dec 30, 2022 / 7 min
The very last days of the old year are probably a good time to think about the next one. Although we already learned how inaccurate any predictions can be, it still feels like an interesting exercise to me. Let’s try to predict the tech future just a little bit… 🔮 I have to warn you, that everything you’ll read here is just a reflection of my own gut feeling. It’s a bunch of guesses based on news, observations, and discussions with my colleagues (👋). It comes with ABSOLUTELY NO WARRANTY, just like a lot of software we’re using every day. Of course, these predictions are also biased by my experience and area of interest, which clearly has a lot to do with Java and JVM.
Read the article

What happens when you only limit the maximum heap size?

#java / Nov 15, 2022 / 13 min
The JVM has spoiled us with its cleverness. It makes so many decisions behind the scenes, that lots of us gave up on looking at what’s inside. Memory-related discussions are probably more likely to appear at a conference or during a job interview than at “real” work. Of course, depending on what you work on. Java apps are often run in containers these days. Built-in container awareness makes the JVM respect various container-specific limits (e.g. CPU, memory). This means, that even when running an app with a dummy java -jar app.jar (which is usually not the best idea), everything should just work. That’s probably why the only memory-related option provided is often the -Xmx flag (or any of its equivalents). In other words, we tend to only limit the maximum heap size, like this:
Read the article

JSON, Kafka, and the need for schema

#kafka / Jul 11, 2022 / 10 min
When I started my journey with Apache Kafka, JSON was already everywhere. From Javascript UIs, through API calls, and even databases - it became a lingua franca of data exchange. For many organizations adopting Kafka I worked with, the decision to combine it with JSON was a no-brainer. Yet, this post is not really about Kafka itself. It’s not another how-to guide either. Using Kafka made me less enthusiastic about JSON and more focused on data evolution aspects. Here, I’d like to share some of my observations with you.
Read the article

The API should guide you

#design / Mar 23, 2022 / 5 min
We create APIs all the time - and I don’t have only libraries and frameworks in mind. Every piece of code that’s intended to be called by another piece of code is an API, in some sense. It’s our job to define an interface, which will be used to achieve whatever is expected. While discussing various API designs, we often focus on “how it’s gonna look” first. Does it allow fluent calls? Does it rely on annotations? Is the naming accurate? Don’t get me wrong - these are all valid questions. Yet, these “visuals” often distract us from the actual usability.
Read the article

Java records & compact constructors

#java / Feb 16, 2022 / 5 min
Java records should be no longer considered as a “new concept”. Introduced in early 2020 (with version 14) have already been adopted in many projects and organizations. Yet, while we all know that they provide getters, equals, hashCode, and toString for free, there is one feature that still feels a bit unknown. Let’s see how compact constructors can help us write more idiomatic code. Record construction Recent versions of Java come with concise syntax for declaring records:
Read the article

Go-live is a test of flexibility

#craftsmanship / Jan 25, 2022 / 5 min
We want our applications to be maintainable, reliable, resilient, and scalable. All these features seem to share the same idea: being flexible. This flexibility is often manifested in the early design documents close to the buzzwords and technology names. But that’s only the marketing. The true test of flexibility comes with the first go-live. “Production will verify” as my former colleagues used to say. Flexibility is usually a good thing. It means being able to adapt. Bending without breaking. Flexibility gives us a margin of error when something unexpected happens. Just like it was “made” with production in mind.
Read the article