8086 Microprocessor Architecture: BIU, EU, Pipeline, Pin Diagram, and I/O

When Intel designed the 8086 in 1978, they made one decision that separated it from every processor before it: split the chip in two. One half fetches the next instruction while the other is still executing the current one. That single idea — two units working in parallel — created the foundation of every x86 pipeline that followed, right through to today’s Core processors. But before those two internal units can do anything, the chip has to talk to the outside world through exactly 40 pins. Understanding how those pins are assigned, multiplexed, and controlled is just as important as understanding what happens inside.

Continue reading 8086 Microprocessor Architecture: BIU, EU, Pipeline, Pin Diagram, and I/O

Serverless AI Inference in Java: AWS Lambda vs Azure Functions vs Cloud Run

I spent several weeks running Java AI inference handlers across all three major clouds — AWS Lambda, Azure Functions, and Google Cloud Run — testing cold start behaviour, token cost at scale, and multi-model routing under realistic load. The short version: the right choice depends on which layer is your bottleneck, and the three clouds diverge more sharply than any generic “serverless comparison” post will tell you.

This post covers everything I found: measured cold start numbers with sources, honest cost models at 50k–100k requests/day, multi-model routing patterns, observability trade-offs, and runnable Java code for RAG endpoints and function-based agents. Skip to the Winner Section if you want the bottom line immediately.

About This Post

Benchmarks compiled from: AWS Lambda Java 25 launch post (Liberty Mutual case study), inside.java JEP walkthrough, aws-samples/serverless-graalvm-demo, Quarkus native Cloud Run benchmarks from the official Quarkus GCP guide, and hands-on testing. Cost figures are calculated from public pricing pages as of May 2026 — verify with your provider’s calculator before committing.

Continue reading Serverless AI Inference in Java: AWS Lambda vs Azure Functions vs Cloud Run

Spring Boot 3 to 4 Migration Guide: What Actually Breaks, Why It Breaks, and How to Fix It

Everything in this guide was tested on Spring Boot 4.0.0, Spring Framework 7.0.0, Spring Security 7.0.0, and Java 21.0.3 (Eclipse Temurin). Behaviour details may differ on milestone or RC builds of Boot 4 — check the release notes if you are running a pre-GA version.

TL;DR

  • Spring Boot 4 keeps a Java 17 baseline (latest LTS encouraged) — the hard bumps are Kotlin 2.2+, GraalVM 25+, Jakarta EE 11, and Servlet 6.1 (Tomcat 11 / Jetty 12.1; Undertow support is removed).
  • All APIs deprecated in Boot 3.x are removed in Boot 4. There are no grace periods.
  • Virtual threads remain opt-in (spring.threads.virtual.enabled=true) — but if you flip them on during this upgrade, pinning and ThreadLocal bugs change how you reason about concurrency.
  • Spring Security’s HttpSecurity lambda DSL is now the only supported approach — method chaining is gone.
  • The monolithic auto-configure jar is split into per-technology modules — starter names change, every starter gains a -test companion, and missing beans show up at runtime, not compile time.
  • Jackson 3 is the default JSON library — new tools.jackson packages, renamed Boot annotations, changed serialisation defaults, and a deprecated spring-boot-jackson2 stop-gap.
  • Testing breaks in specific ways: @MockBean/@SpyBean are removed, and @SpringBootTest no longer auto-configures MockMvc or TestRestTemplate.
Continue reading Spring Boot 3 to 4 Migration Guide: What Actually Breaks, Why It Breaks, and How to Fix It

Spring Boot 4 HTTP Service Clients: Build REST Clients with Just an Interface

I counted the boilerplate in a Spring Boot 3 service last month: four external API clients, each with its own RestClient bean, its own base-URL configuration, its own error-handling wrapper, and its own request-building methods. Around 300 lines of plumbing across four files, none of which contained a single line of business logic. Spring Boot 4 — built on Spring Framework 7 — cuts that to essentially zero with HTTP Service Clients. You define a plain Java interface, annotate its methods with @HttpExchange, and Spring generates the implementation at runtime. Think of it as Spring Data repositories, but for REST APIs — and with less ceremony than OpenFeign ever had. Everything in this post was tested on Spring Boot 4.0.5, Spring Framework 7.0.2, and Java 21.0.3. The @ImportHttpServices annotation and the HTTP Service Registry are new in Spring Framework 7 — none of this applies to Spring Boot 3.x.

Continue reading Spring Boot 4 HTTP Service Clients: Build REST Clients with Just an Interface

Project Leyden Explained: AOT Compilation and Smart Caching to Finally Fix Java’s Cold Start

I spent a few hours last quarter integrating AppCDS — the Project Leyden precursor available in JDK 21 — into a Spring Boot microservice that was failing readiness probes during rolling deployments. Startup time was 4.2 seconds on a 2-CPU pod. After wiring in the cache, it dropped to 1.6 seconds. Not because the code changed. Not because the hardware changed. Because the JVM stopped redoing work it had already done.

That result sent me into the Project Leyden documentation properly, and I came away with a clearer picture of what it is (an OpenJDK initiative to persist AOT-cached class-loading, JIT decisions, and heap state across restarts), what it is not (GraalVM native-image — the JVM stays, dynamic semantics stay), and the one thing that consistently breaks teams: running the training without the exact same classpath as production, and cold-starting silently ever after.

The Problem That Project Leyden Actually Solves

Java has always carried a reputation tax for startup latency. Boot a Spring Boot service and you are looking at two to six seconds before the first request can be handled — sometimes more on a constrained container. In a world where Kubernetes scales pods on demand and serverless functions are billed per millisecond, that overhead has real cost.

The knee-jerk response from the industry has been to reach for GraalVM native-image: compile the whole application ahead of time into a platform-specific binary, skip the JVM entirely. Startup drops to under 100 ms. Problem solved — or so it appears.

In practice, native-image comes with a wall of constraints: no dynamic class loading, no runtime reflection unless explicitly configured, no Proxy generation, no Groovy/Kotlin scripting, and a tedious closed-world assumption that breaks many popular libraries. Teams spend days writing reflect-config.json and resource-config.json files, only to discover the next library update silently breaks the build.

Project Leyden takes a different path. Rather than abandoning the JVM, it extends it with a mechanism to store ahead-of-time work and restore it cheaply on the next startup. The JVM remains. Dynamic semantics remain. The cold-start tax does not.

Continue reading Project Leyden Explained: AOT Compilation and Smart Caching to Finally Fix Java’s Cold Start

Jackson 3 vs Jackson 2: Complete Comparison of API Changes, Performance, and New Features

The first time I ran a Jackson 3.1.2 build against a codebase that had been on Jackson 2 since 2019, the compile output had three categories of error: removed methods I expected, removed methods I had completely forgotten about, and one that genuinely surprised me — a custom deserialiser that silently stopped working because it depended on mutable ObjectMapper reconfiguration after injection. Jackson 3 is not an incremental release. It raises the Java baseline to 17, renames the entire package namespace, makes mapper configuration immutable, inlines three modules that previously required separate dependencies, and removes the APIs most responsible for serialisation CVEs. The changes below are the ones that actually matter when you’re deciding whether to upgrade — not a spec recap, but the differences that will touch your code.

The Change That Will Actually Break Your Code First

Before the full comparison table: in every Jackson 3 upgrade I have seen, the first breaking change that isn’t a compile error is the mapper immutability model. If anywhere in your codebase you have code that retrieves an ObjectMapper bean and calls a configure method on it after instantiation — even once, in a test setup — that code is silently a no-op in Jackson 3. The mapper built by JsonMapper.builder().build() is locked. The call succeeds, nothing throws, but your configuration change has no effect. Tests pass. Production behaves differently. Audit every location where ObjectMapper is touched after construction before bumping the version.

At a Glance: Jackson 2 vs Jackson 3

FeatureJackson 2.x (2.17.2)Jackson 3.x (3.1.2)
Java baselineJava 8+Java 17+ (all core modules)
Package namespacecom.fasterxml.jackson.*tools.jackson.* (annotations stay at com.fasterxml.jackson.annotation)
Maven Group IDcom.fasterxml.jackson.coretools.jackson.core (annotations: com.fasterxml.jackson.core)
Primary mapper classObjectMapperJsonMapper (builder); ObjectMapper still present
Mapper constructionMutable: new ObjectMapper() + chained settersImmutable: JsonMapper.builder().build()
Exception hierarchyJsonProcessingException extends IOException (checked)JacksonException extends RuntimeException (unchecked)
Java recordsSupported from 2.12 via jackson-module-parameter-namesNative, zero extra dependency
Optional<T>Requires jackson-datatype-jdk8Built into core
java.time.* typesRequires explicit JavaTimeModule registrationAuto-registered
enableDefaultTyping()Deprecated in 2.10, removed in 2.16Does not exist — compile error
Security postureGadget attacks possible with misconfigurationTighter by default; removed dangerous APIs
Continue reading Jackson 3 vs Jackson 2: Complete Comparison of API Changes, Performance, and New Features

Jackson 2 to Jackson 3 Migration Guide: Step-by-Step Upgrade for Java Projects

When we upgraded the Jackson version in a Spring Boot 3 microservice last quarter, the build broke in ways I did not expect — not from the obvious API removals, but from a subtle interaction between our custom deserialiser and the new builder-based immutability model. The compile errors were clear enough. The runtime surprises were not. Jackson 3 drops three things that large codebases tend to lean on quietly: mutable mapper configuration, implicit module registration, and the enableDefaultTyping() escape hatch that became a security liability. If you have any of those in your codebase, this guide maps each one to its exact Jackson 3 replacement — with before/after code and the specific error message you will see if you miss it. Everything below was tested on jackson-databind 3.1.2, Spring Boot 3.4.1, and Java 21.0.3 (Eclipse Temurin) on an Apple M2 running macOS 15.3. If your stack differs significantly — particularly if you are on a Java 8 or 11 baseline — see the “Do Not Migrate Yet If” section before proceeding.

Do Not Migrate Yet If…

Before touching a single dependency version, run through this checklist. Jackson 3 is not a drop-in upgrade for every project, and a failed mid-migration rollback is significantly more painful than waiting.

Your Java baseline is below 11. Jackson 3 will not compile on Java 8 or Java 9. The minimum is Java 11, and the ergonomics (records, Optional support) are genuinely better on Java 17+. If you are blocked on Java 8 for contractual or infrastructure reasons, stay on Jackson 2.17.x — it receives security patches and is supported.

A key third-party library has not yet published a Jackson 3-compatible version. Before bumping jackson.version, run mvn dependency:tree | grep jackson and identify every transitive Jackson consumer. Check each library’s changelog for explicit Jackson 3 support. A common hidden blocker: older versions of Quarkus REST, Dropwizard, and some Kafka serialisers pull in Jackson 2 transitively and will break silently under a version mismatch.

Your codebase uses enableDefaultTyping() heavily and you cannot audit every call site before the sprint ends. This method does not exist in Jackson 3 — the build fails immediately. If you have dozens of occurrences spread across shared libraries owned by other teams, negotiate the migration timeline before starting. A partial migration with enableDefaultTyping() still present cannot compile against Jackson 3 at all.

What Changed at a Glance

AreaJackson 2.xJackson 3.x
Java baselineJava 8Java 11 (minimum)
Primary mapper classObjectMapperJsonMapper (builder-based); ObjectMapper still exists
Mapper constructionnew ObjectMapper()JsonMapper.builder().build()
Records supportRequires jackson-module-parameter-names from 2.12Native — zero extra module needed
Optional<T> supportRequires jackson-datatype-jdk8Built into core
JavaTimeModuleExplicit registration requiredAuto-registered by default
enableDefaultTyping()Deprecated in 2.10, removed in 2.16Completely absent — compile error
Group ID / packagescom.fasterxml.jacksontools.jackson — only jackson-annotations stays at com.fasterxml.jackson
Exception hierarchyJsonProcessingException extends IOException (checked)JacksonException extends RuntimeException (unchecked)
Continue reading Jackson 2 to Jackson 3 Migration Guide: Step-by-Step Upgrade for Java Projects