Java logo

Languages & Frameworks

Official site

Java

Java — a strongly typed JVM language with a long upgrade path, where the interesting failures live in the toolchain and the runtime.

Overview

Java is the language behind my tutorials and experiments on annotation processing, messaging, architecture rules, and MCP servers. Each of those articles ships with a repository, so its claims can be run rather than taken on trust.

I pay most attention to what the language does behind the source code. Project Lombok is a good example: a ten-line class becomes 80 lines of plain Java at compile time, and the bugs that follow sit in code nobody reads.

The toolchain deserves the same scrutiny. Lombok reaches inside the compiler and relies on Unsafe, so a new JDK can break it. When I switched that access off, the compiler crashed and produced nothing.

Modern Java reduces how much of that machinery is needed. Records, final since Java 16, cover immutable data carriers, and I compare them with Lombok directly instead of treating either as the default.

Architecture decisions can be enforced in Java too. With ArchUnit on Java 25 I turn a decision record into a test, and I measured what such rules change for an AI agent working in a small modular-monolith shop.

Runtime details matter when something crosses a process boundary. Writing an MCP server against the official Java SDK on JDK 27 showed how one log line on stdout can end a session in the client, and how the iteration order of an immutable Map changes between JVM runs.

How I Work With Java

I start with what the compiler and the JVM actually do. If a tool generates code, I read the generated code before I rely on it.

I pick the plainest language feature that fits. A record comes first for immutable data, and Lombok has to earn its place in the class it is used on.

I keep generated code away from JPA entities unless I have checked it. Generated equals, hashCode and toString are exactly where @Data causes trouble there.

I test upgrades before I trust them. A new JDK can break compiler-level tooling, so I run the build against the versions I care about instead of assuming it will pass.

I write important decisions down and make them executable where I can. A record explains why, and an ArchUnit rule catches the code that breaks it.

I back behaviour claims with a test or a recorded run, and I state the versions used, because the answer often changes with them.

Key Capabilities

Tutorials and measurements on Java 25 and JDK 27, each with a runnable repository.
Project Lombok: what it generates, how it hooks into the compiler, and how to leave it.
Architecture decisions enforced as ArchUnit tests.
MCP servers built on the official Java SDK.
RabbitMQ messaging tested against a real broker.