Codepocalypse Now LangChain4j vs Spring AI Baruch Sadogursky Viktor Gamov

@jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Smart Home Demo ————————————————————————————————————————————— Ask my house anything: • • • • • • @jbaruch “What was the last thing that happened?” “What’s the most active room today?” “What’s using the most power right now?” “Any water leaks detected?” “How many devices do you have?” “What time did everyone leave this morning?” @gamussa #codepocalypse speaking.jbaru.ch

The Challenge ————————————————————————————————————————————— OpenClaw - 350,000+ GitHub stars A personal AI agent that manages your life. Written in TypeScript. Can Java do this? • • • • • • @jbaruch [ [ [ [ [ [ ] ] ] ] ] ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Pick a Side ————————————————————————————————————————————— ▓▓▓ Special Agent Johnson ▓▓▓ Special Agent Johnson Spring AI Division LangChain4j Division @jbaruch @gamussa No relation. @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Rules of Engagement ————————————————————————————————————————————— • • • • • @jbaruch Same feature, same time limit Both build against the same LLM Audience votes at the end Failures count (they always happen) The real winner = Java developers @gamussa #codepocalypse speaking.jbaru.ch

██ ROUND 1 ▓▓▓ The Basic Agent @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 1 - The Basic Agent ————————————————————————————————————————————— • • • • • • @jbaruch [x] [ ] [ ] [ ] [ ] [ ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 1 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI ▒▒▒▒ LangChain4j @RestController class AgentController { @RegisterAiService interface Agent { private final ChatClient chat; String chat(String message); AgentController(ChatClient.Builder b) { this.chat = b.build(); } } // That’s it. No controller needed // with Quarkus REST integration. @PostMapping(“/chat”) String chat(@RequestBody String msg) { return chat.prompt(msg) .call() .content(); @jbaruch } } @gamussa #codepocalypse speaking.jbaru.ch

██ ROUND 2 ▓▓▓ Memory @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 2 - Memory ————————————————————————————————————————————— • • • • • • @jbaruch [x] [x] [ ] [ ] [ ] [ ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 2 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI ▒▒▒▒ LangChain4j ChatClient.builder(model) .defaultAdvisors( MessageChatMemoryAdvisor .builder(chatMemory) .build() ) .build(); @RegisterAiService interface Agent { // Memory is an Advisor. // It wraps the pipeline. // Every advisor can see it. // Memory is just… there. // Declare it, it works. // No wrapping ceremony. @MemoryId String chat(@MemoryId String id, String message); } Philosophy - Advisor middleware vs declarative injection @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

██ ROUND 3 ▓▓▓ Tools @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 3 - Tools ————————————————————————————————————————————— • • • • • • @jbaruch [x] [x] [x] [ ] [ ] [ ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 3 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI @Component public class ConferenceTools { @Tool(description = “Search CFPs”) public String searchCfps(String kw) ▒▒▒▒ LangChain4j McpClient mcp = McpClient.using( new StdioMcpTransport( “developer-events-mcp” ) ).build(); { // Direct HTTP call. No MCP. // No protocol. No middleware. return http.send(req, ofString()) .body(); } } // “Models are smart enough to // call APIs directly.” @jbaruch McpToolProvider tools = McpToolProvider.builder() .mcpClients(mcp) .build(); // “MCP discovers tools at // runtime. Yours are hardcoded.” @gamussa - Direct @Tool calls vs MCP#codepocalypseovery speaking.jbaru.ch

██ THE SECRET WEAPON @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

How Are We Coding This Fast? ————————————————————————————————————————————— We gave our coding agents the right context. # Baruch’s setup (Spring AI) tessl install jbaruch/spring-ai-agent jbaruch/spring-boot-4

Viktor’s setup (LangChain4j) tessl install jbaruch/langchain4j-ai-agent jbaruch/quarkus-langchain4j Tessl plugins - versioned context packages for coding agents. Zero hallucinated APIs. One command.

@jbaruch @gamussa #codepocalypse speaking.jbaru.ch

The Proof ————————————————————————————————————————————— Real eval numbers. With tiles, agents write working code. Without, they hallucinate APIs. @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

██ ROUND 4 ▓▓▓ Agentic Workflows @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 4 - Agentic Workflows ————————————————————————————————————————————— • • • • • • @jbaruch [x] [x] [x] [x] [ ] [ ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 4 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI // Agents = composed advisors // Skills = markdown folders // No special agent module @jbaruch ▒▒▒▒ LangChain4j @SequentialAgent interface Pipeline { @AgentMember ClassifierAgent classifier(); ChatClient.builder(model) .defaultAdvisors( memoryAdvisor, toolCallAdvisor, guardrailAdvisor ) .build(); } // Spring says agents are just // well-composed services. // LangChain4j says agents ARE // special. Dedicated module. @AgentMember EmailAgent emailHandler(); @AgentMember CalendarAgent calAgent(); @gamussa - Composed services vs firs#codepocalypse speaking.jbaru.ch

██ ROUND 5 ▓▓▓ Guardrails @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 5 - Guardrails ————————————————————————————————————————————— • • • • • • @jbaruch [x] [x] [x] [x] [x] [ ] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 5 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI @jbaruch ▒▒▒▒ LangChain4j // Guardrails = …also advisors ChatClient.builder(model) .defaultAdvisors( inputGuardrailAdvisor, memoryAdvisor, toolCallAdvisor, outputGuardrailAdvisor ) .build(); class InjectionGuard implements InputGuardrail { // Same pattern. Everything // composes. One ring to rule // them all. } @Override public InputGuardrailResult validate(UserMessage msg) { if (isInjection(msg)) return fatal(“Blocked”); return success(); } // Typed interfaces. Type-safe. // Explicit. Purpose-built. @gamussa - Advisor chain validation #codepocalypserail interfaces speaking.jbaru.ch

██ ROUND 6 ▓▓▓ Observability @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Round 6 - Observability ————————————————————————————————————————————— • • • • • • @jbaruch [x] [x] [x] [x] [x] [x] @gamussa Basic agent Memory Tools Agentic workflows Guardrails Observability #codepocalypse speaking.jbaru.ch

Round 6 - Comparison ————————————————————————————————————————————— ▒▒▒▒ Spring AI // // // // One dependency. Spring Boot Actuator. Micrometer. Prometheus. Grafana. // // // // Every ops team already knows these tools. Production-grade. Standards-based. ▒▒▒▒ LangChain4j AgentMonitor monitor = AgentMonitor.create(); // // // // HTML topology report. Agent execution tree. Token usage per agent. Timing per decision. // Shows WHY the agent // did what it did. Philosophy - Ecosystem metrics vs agent-specific decision trees @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

██ THE VERDICT @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

The Abstraction War ————————————————————————————————————————————— │ Spring AI │ LangChain4j ──────────────┼───────────────────────┼─────────────────────── Basic agent │ ChatClient builder │ @AiService interface Memory │ Advisor middleware │ Declarative injection Tools │ Direct @Tool (no MCP) │ MCP protocol discovery Agentic │ Composed advisors │ Dedicated module Guardrails │ …also advisors │ Typed interfaces Observability │ Micrometer native │ AgentMonitor tree │ Spring AI │ LangChain4j ────────────┼────────────────────────────┼────────────────────────────── Philosophy │ One pattern for everything │ Right abstraction per concept Real winner │ Java developers │ Java developers @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

The Winner Is… ————————————————————————————————————————————— ██ Your team’s philosophy. Spring shop? Spring AI feels like home. The advisor pattern IS the Spring way. Framework independence? LangChain4j delivers. Quarkus, plain Java, most mature agentic module. Both built an OpenClaw in 75 minutes. Both work. @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

The REAL Winner ————————————————————————————————————————————— ██ Java Developers Two production-ready AI frameworks. In Java. In 2026. You don’t need TypeScript. You don’t need Python. Your existing skills, ecosystem, and infrastructure - it all works. The codepocalypse isn’t about code dying. It’s about code evolving. @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Resources ————————————————————————————————————————————— speaking.jbaru.ch/codepocalypse-now-2026 Slides, code, links to both frameworks, comparison table @jbaruch @gamussa #codepocalypse speaking.jbaru.ch

Vote! ————————————————————————————————————————————— ▓▓▓ Spring AI ▓▓▓ LangChain4j cheer if Spring won cheer if LangChain4j won ██ Thank you! @jbaruch - @gamussa Never trust a monkey with your codebase. Even an AI monkey. @jbaruch @gamussa #codepocalypse speaking.jbaru.ch