# langchain4j-interop Companion code for [Spring AI vs LangChain4j in 2026: Is the Pairing Still Worth It?](https://ankurm.com/spring-ai-langchain4j-production-ai-microservices-java/), part of the [Spring AI series](../README.md) on ankurm.com. One order-support assistant built twice, once with Spring AI 2.0.1 and once with LangChain4j 1.22.0, in one Spring Boot 4.1.1 project, against a local fake OpenAI server (no vendor API is called). The tests answer five questions and `scripts/compile-old-snippets.sh` answers a sixth. Every figure in the article is quoted from a file in [`output/`](output). | File | Question | |---|---| | `01-both-starters.txt` | What happens when both OpenAI starters are on the classpath? | | `02-same-assistant.txt` | Same assistant, same question: what differs on the wire? | | `03-tool-throws.txt` | A tool that throws, and a model that will not stop calling it: what bounds the loop? | | `04-observability.txt` | Which meters does each framework record? | | `05-mcp-first.txt` | One MCP tool server consumed from both frameworks | | `06-old-code-vs-current.txt` | Which lines from the original (2025) article still compile, and do its Maven coordinates still exist? | ## Versions Spring Boot 4.1.1, Spring AI 2.0.1, LangChain4j 1.22.0 (`langchain4j-open-ai-spring-boot4-starter` and `langchain4j-spring-boot4-starter` are 1.22.0-beta32, beta only), Java 25. ## Run ```bash scripts/run-all.sh # tests -> output/01..05, then the old-snippet check -> output/06 ``` No services are needed. Script 06 looks up Maven Central (it retries on rate limiting); `src/broken/` holds the old snippets, one per file, which are compiled outside the main build on purpose.