Shaaf's blog

A technical blog about Java, Kubernetes and things that matter

Java+LLMs: A hands-on guide to building LLM Apps in Java

I had the pleasure to present about building Java applications using LLMs together with Bazlur at GeeCon 2025. The weather was amazing and Krakow is a beautiful historical city.

Key Topics Covered

Here are the key topics from the video with direct links to those sections:

  • LangChain4j Basics: An introduction to the framework, demonstrating how it abstracts communication with various LLMs like OpenAI and Gemini using builder patterns.
  • Prompt Engineering: The speakers explain the difference between System Prompts (defining the AI’s behavior/personality) and User Prompts (the specific query).
  • AI Services & Streaming: A look at how to create high-level interfaces for AI interactions, including streaming responses for real-time chat experiences.
  • Memory Management: How to provide LLMs with context from previous conversations using providers like MessageWindowChatMemory and storing history in databases.
  • Tools (Function Calling): A deep dive into how LLMs can trigger Java methods to perform specific tasks, such as fetching web content or compiling Java code.
  • Jakarta EE Project Generator: A demonstration of using an LLM tool to generate a complete Jakarta EE project structure via a chat interface.
  • Retrieval-Augmented Generation (RAG): Using PGVector and embedding models to store and retrieve private data efficiently.
  • Chunking and Tokenization: The importance of segmenting data so the AI receives the right context without exceeding token limits.
  • Model Context Protocol (MCP): An introduction to the standard for connecting AI models to external data sources and tools.
  • Q&A Session: Discussions on prompt injection, guardrails, and testing non-deterministic AI outputs.

Next up we are both busy building a workshop about Langchain4j and its integration with Spring. If you are interested in learning more join us at JNation.pt. Bring your laptop the session will be 180 minutes and lots to code about ;)


Two Essential Patterns for Building MCP Servers

When building Model Context Protocol (MCP) servers, I learned two critical design patterns the hard way. What started as a straightforward implementation of a Keycloak administration server quickly became unwieldy—until I discovered Intent Multiplexing and the Command Pattern. Together, these patterns transformed a maintenance nightmare into an elegant, extensible architecture.

This post shares those lessons so you can avoid the same pitfalls.

Replicate each operation from your API and viola! you have a tool explosion. And that might not seem evident in the first place, but becomes a serious problem. An LLM might not be able to handle that large context, it might even start to halluncinate.


Keycloak MCP Server: Manage Identity with Natural Language

There is always a distinct thrill in learning something new and immediately putting it to the test. My journey with Model Context Protocol (MCP) servers began with a basic ‘books API’ demo, but I quickly wanted to take it a step further and build something with real-world utility. Since I enjoy working with Keycloak, I thought: Why not create an MCP server for it?

The vision was simple: enable developers to just ‘chat’ with Keycloak. There are so many standard tasks—setting up new users, groups, clients, and browser workflows—that could be streamlined through conversation. For those unfamiliar, Keycloak is an open-source identity and access management solution. I released the first experimental version this past summer, and since then, the wave of constructive community feedback has been incredible. That momentum is exactly what gets me excited to keep building.


Complete local setup development guide for Konveyor Analyzer-lsp 🚀

Build, test, and develop Kantra rules locally with full JDT-LS and multi-language provider support. Some content in this post was generated using an LLM.

Modernizing large, complex codebases is a significant challenge. Identifying migration blockers, deprecated APIs, and technology-specific patterns requires deep, accurate code analysis. The Konveyor Analyzer LSP is engineered to solve this problem by providing a flexible and powerful static analysis engine. It uniquely leverages the Language Server Protocol (LSP) to tap into rich, IDE-level code intelligence for multiple languages.


My first 6 hours with Rust

TLDR; I took a day off from work today, although still most of my time I ended up doing my travel expenses. Talk about priorities. I am the one to blame here totally. 😄

So come around lunch time, thats when all the fluids are ready to do something different. I ended up exploring some basics about Rust. I heard a friend once said, if a prominent person (wonder who that is..) says billions over and over again, somehow people just start believing in billions. Anyways I am totally sold by my youtube feed to explore this a bit. What is this rust thing? And before I go any further, just to let you know I like programming languages and problem solving. I am not hung up on one language. I appreciate them all. Except MS access (oops)