Skip to content

Repository files navigation

Building AI Agents in Java — Companion Code

A from-scratch, runnable, tested implementation of every code example in Building AI Agents in Java (2026 Edition) — the LangChain4j/Spring AI book in Building AI Agents in Java.pdf / .docx in this repo.

Two Maven modules:

Module Covers Stack
core/ Chapters 2–4, 6–12, 14 Plain Java 21, LangChain4j 1.17.2
support-service/ Chapter 13 (AcmeSupport case study) Spring Boot 4.1.0, Spring AI 2.0.0

Chapters 1 and 5 are conceptual/comparative and have no standalone examples of their own; their code shows up inside the Chapter 6+ examples (Chapter 1's agent loop is Chapter 6's TaskAgent; Chapter 5's AI Services pattern is used throughout core, and its Spring AI ChatClient counterpart is support-service's RagConfig/SupportController).

Requirements

  • Java 21+ (developed and tested on Temurin 21.0.2)
  • Maven 3.9+
  • Nothing else to run the test suite — see "What runs offline" below.
  • An OPENAI_API_KEY (and/or a local Ollama daemon) only if you want to actually run the main() demos or the live-API tests against a real model.

Running

mvn test              # whole reactor: 57 tests, all green, zero external dependencies
mvn -pl core test      # just the plain-Java chapters
mvn -pl support-service test   # just the Spring Boot case study

# Run an individual chapter demo (needs OPENAI_API_KEY):
export OPENAI_API_KEY=sk-...
mvn -pl core exec:java -Dexec.mainClass=com.example.aiagents.ch06_first_agent.TaskAgentDemo

# Run the full AcmeSupport service (needs OPENAI_API_KEY):
mvn -pl support-service spring-boot:run
curl -s -X POST localhost:8080/support/message \
  -H 'X-Customer-Id: cust-priya' -H 'Content-Type: application/json' \
  -d '{"text":"Can I return a used blender after 40 days?"}'

What runs offline vs. what needs live credentials

The design goal was a suite that is genuinely green with no API key and no network, not one that fakes success by skipping everything. Three techniques make that possible:

  1. A local, in-process embedding model (AllMiniLmL6V2EmbeddingModel, Chapter 3/9) runs real ONNX inference with no network call, so Chapter 9's RAG ingestion/retrieval tests do real chunking, real vector embedding, and real cosine-similarity ranking — not mocks.
  2. A hand-rolled FakeChatModel (core's com.example.aiagents.testkit.FakeChatModel, and support-service's test-only equivalent) implements the real ChatModel interface with scripted responses, including tool-call requests. This exercises the actual LangChain4j/ Spring AI tool-calling loop end to end — real tool method invocation, real memory, real structured-output parsing — with a deterministic, offline "model." This is exactly what Chapter 14.3 recommends: "mock the model in unit tests... reserve real-model evaluation for the dedicated eval suite."
  3. A local HTTP stub server (java.net.http's own HttpServer) stands in for the OpenAI API in RawChatClientTest, so even the hand-rolled Chapter 4 HTTP client is tested against a real request/response cycle, not skipped.

A small number of tests are the genuine exception and self-skip via JUnit's Assumptions when their precondition isn't met, rather than failing the build:

  • HelloLiveSmokeTest, OllamaHelloLiveSmokeTest, ConfigTest — skip without OPENAI_API_KEY / a reachable Ollama daemon. Set the env var / start Ollama and they run for real.
  • EmbeddingsDemoTest, RagIngestionRetrievalTest — skip only on the one platform combination where they can't: see the caveat below. They run for real on Linux (x86_64/arm64), Apple Silicon, and Windows.

Known platform caveat: DJL native library gap on Intel macOS

AllMiniLmL6V2EmbeddingModel's tokenizer (ai.djl.huggingface:tokenizers:0.36.0) ships prebuilt native binaries for linux-x86_64, linux-aarch64, osx-aarch64 (Apple Silicon), and win-x86_64 — but not osx-x86_64 (Intel Mac). On that one platform, loading the model throws at class-init time. core's testkit.LocalEmbeddingModelSupport detects this and skips the affected tests with an explicit message rather than failing opaquely; the example code itself (EmbeddingsDemo, RagDemo) is unchanged and correct — it just can't load its native dependency on this specific host. This is an upstream DJL packaging gap, not a bug in the example.

Chapter map (core)

Chapter Section(s) Package
2 Setup, API keys, Hello/Ollama smoke tests, logging ch02_setup
3 Embeddings ch03_models
4 Raw HTTP client, framework chat, streaming, structured output ch04_talking
5 AI Services pattern ch05_frameworks
6 Tools, first agent, guardrails ch06_first_agent
7 MCP client consumption ch07_mcp
8 Prompt chaining, routing, parallelization, evaluator-optimizer ch08_patterns
9 Conversation memory, RAG ingestion/retrieval ch09_memory_rag
10 Multi-agent supervisor, typed hand-offs ch10_multiagent
11 Retries/circuit breakers, virtual threads, idempotency ch11_resilience
12 Token budgets, untrusted-content labeling, audit log ch12_security
14 Property-based evaluation harness ch14_eval
Offline ChatModel test double testkit

Chapter 13 lives entirely in support-service (domain, tools, security, config, web packages) — see its Javadoc-style comments for the section-by-section mapping to the AcmeSupport case study.

Deliberate deviations from the book's exact code

The book targets a fast-moving 2026 ecosystem; a few APIs shifted slightly between when it was written and the versions actually on Maven Central today. Notable spots, each called out in a comment at the point of use:

  • Spring AI 2.0's advisors are builder-based (QuestionAnswerAdvisor.builder(store).build()) where the book shows constructors (new QuestionAnswerAdvisor(store)).
  • LangChain4j's @P/tool reflection needs -parameters at compile time to see real parameter names; both modules' POMs enable it explicitly.
  • The MCP and agentic modules (langchain4j-mcp, langchain4j-agentic) are still beta-versioned (1.17.2-beta27), exactly as the book describes and warns about.

About

Runnable, tested companion code for every chapter of Building AI Agents in Java (2026) — LangChain4j + Spring AI, tool calling, MCP, RAG, multi-agent orchestration, and a full Spring Boot case study. 57 tests, all pass fully offline.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages