2.9 KiB
2.9 KiB
kafka-basics — producer, consumer and serialisation, from nothing
Companion project for Spring Boot 4.1 and Apache Kafka: Producer, Consumer and Serialisation from Scratch on ankurm.com.
Eight tests against a real Kafka broker, started in-process in KRaft mode. No Docker daemon,
no local Kafka install, no ZooKeeper. ./scripts/run-all.sh regenerates everything under
docs/output/.
Versions
| Version | Notes | |
|---|---|---|
| JDK | 25 (Temurin 25.0.4.1+1) | current LTS |
| Spring Boot | 4.1.1 | GA of the 4.1 line was 10 June 2026 |
| Spring Kafka | 4.1.1 | Boot-managed |
| kafka-clients | 4.2.1 | Boot-managed. Central has 4.3.1; let the BOM decide |
| Jackson | 3.1.5 (tools.jackson) |
why JacksonJsonSerializer and not JsonSerializer |
| Testcontainers | 2.0.5 | artifact is testcontainers-kafka, not kafka |
Versions were read from repo1.maven.org/.../maven-metadata.xml and from Boot's own
spring-boot-dependencies POM, not from release announcements.
Quickstart
./scripts/run-all.sh # runs every test and regenerates docs/output/
mvn test # the same thing without the capture
Documentation
- The on-ramp, and the dependency that is not the one you remember
- Producing, and the return value everybody throws away
- Serialisation: two Jackson families
- Keys and partitions: the ordering guarantee in disguise
- Consuming
- Acknowledgement, and a property that is not where you look for it
- Testing without installing Kafka
Captured output
| File | Produced by |
|---|---|
effective-config.txt |
client defaults vs Boot's overrides vs effective |
key-to-partition.txt |
real placement against a real broker |
serialised-payload.txt |
the Jackson 3 wire format |
tests.txt |
8 tests |
Four things this module exists to prove
spring-kafkaalone gives you no auto-configuration under Boot 4. You needspring-boot-starter-kafka; the symptom is a missingKafkaTemplatebean.JsonSerializeris the Jackson 2 one. It cannot write ajava.time.Instantwith its default mapper.JacksonJsonSerializeris the Jackson 3 one and can.- The default partitioner is
murmur2 & 0x7fffffff, notMath.abs(murmur2). They disagree on two of the six keys in the committed transcript. ConsumerFactory.isAutoCommit()answerstruewhile no consumer auto-commits. The container overrides the property per-consumer and never tells the factory.