Artificial Intelligence is transforming how we build modern software applications. Whether it’s intelligent chatbots, document summarizers, or contextual assistants, integrating AI capabilities directly into Java-based backends is now easier than ever. Traditionally, integrating AI into Java required complex external API calls or Python bridges, but modern frameworks like Quarkus and LangChain4j have simplified this process significantly.

In this article, we will explore how to build AI-infused Java applications using Quarkus and LangChain4j, step by step. We will set up a Quarkus project, add LangChain4j, integrate a language model (like OpenAI or Ollama), and implement a few AI-driven features—all with clean, idiomatic Java code.

Understanding Quarkus and LangChain4j

Before diving into the code, let’s briefly understand what these two powerful tools bring to the table.

Quarkus is a modern, cloud-native Java framework designed for GraalVM and OpenJDK HotSpot. It’s known for its lightning-fast startup times, low memory footprint, and seamless developer productivity features. It’s an excellent choice for building microservices or serverless applications.

LangChain4j, on the other hand, is a Java library that brings LangChain-style AI orchestration to the JVM ecosystem. Inspired by the Python-based LangChain framework, LangChain4j allows developers to easily:

  • Connect to LLMs (Large Language Models)

  • Build prompt templates

  • Manage chat memory

  • Create agents and tools

  • Process documents using embeddings and vector stores

When used together, Quarkus + LangChain4j enables developers to build robust, scalable, and AI-powered Java microservices that can handle complex NLP (Natural Language Processing) tasks natively.

Setting Up Your Quarkus Project

To begin, we’ll set up a new Quarkus project. You can generate one quickly using the Quarkus CLI or Maven archetype.

mvn io.quarkus.platform:quarkus-maven-plugin:create \
-DprojectGroupId=com.example \
-DprojectArtifactId=ai-quarkus-langchain4j \
-DclassName="com.example.AiResource" \
-Dpath="/ai"

Once generated, navigate into your project folder:

cd ai-quarkus-langchain4j

Open the project in your favorite IDE (IntelliJ IDEA, VS Code, or Eclipse).

Adding LangChain4j Dependencies

Next, we need to include the LangChain4j library and a compatible LLM provider. You can choose between multiple providers—OpenAI, Azure OpenAI, or Ollama (for local models like Llama or Mistral).

Add the following dependencies to your pom.xml:

<dependencies>
<!-- Quarkus RESTEasy Reactive for REST endpoints -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<!– LangChain4j Core –>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.31.0</version>
</dependency><!– OpenAI Integration –>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-openai</artifactId>
<version>0.31.0</version>
</dependency><!– Optional: Ollama (for local inference) –>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama</artifactId>
<version>0.31.0</version>
</dependency>
</dependencies>

After adding these dependencies, reload your Maven project to download and integrate them.

Configuring Your LLM Provider

Next, we’ll configure LangChain4j to connect to a language model. You can either use OpenAI’s API or run Ollama locally.

For example, if you’re using OpenAI, add your API key in application.properties:

quarkus.http.port=8080
openai.api.key=sk-REPLACE_WITH_YOUR_KEY

If you’re using Ollama (a local LLM runtime), simply ensure you have Ollama installed and a model like llama3 available:

ollama pull llama3

Creating an AI-Powered Service in Quarkus

Now, let’s create a simple service that communicates with the LLM.
Inside src/main/java/com/example/, create a new file called AiService.java.

package com.example;

import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiService;
import dev.langchain4j.service.SystemMessage;

@AiService
public interface AiService {

@SystemMessage(“You are an expert Java assistant. Answer concisely and clearly.”)
String chat(String userMessage);

static AiService create(String apiKey) {
var model = OpenAiChatModel.builder()
.apiKey(apiKey)
.modelName(“gpt-4o-mini”) // or any available model
.build();

return AiServiceFactory.create(AiService.class, model);
}
}

This interface uses the LangChain4j service annotation model, which automatically creates a proxy implementation that interacts with the underlying LLM. The @SystemMessage defines the AI’s behavior and tone, ensuring consistent responses.

Exposing an AI REST Endpoint

Next, let’s expose our AI service as a REST endpoint using Quarkus’s RESTEasy Reactive.

Edit the existing AiResource.java file (created during project generation):

package com.example;

import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path(“/ai”)
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class AiResource {

private final AiService aiService;

public AiResource() {
this.aiService = AiService.create(System.getenv(“OPENAI_API_KEY”));
}

@POST
@Path(“/chat”)
public Response chat(UserMessage request) {
String reply = aiService.chat(request.message());
return Response.ok(new AiReply(reply)).build();
}

public record UserMessage(String message) {}
public record AiReply(String response) {}
}

Now you can send a POST request to your endpoint using a JSON payload:

curl -X POST http://localhost:8080/ai/chat \
-H "Content-Type: application/json" \
-d '{"message": "Explain what Quarkus is in simple terms."}'

And you should get an intelligent AI-generated response!

Adding Context Memory to Your Chat

LangChain4j supports conversational memory, enabling the AI to remember previous exchanges. This is essential for creating chatbots or virtual assistants that maintain context.

Let’s extend our service to include memory.

package com.example;

import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiService;
import dev.langchain4j.service.SystemMessage;

@AiService
public interface MemoryAiService {

@SystemMessage(“You are a helpful assistant with memory of the conversation.”)
String chat(String message);

static MemoryAiService create(String apiKey) {
var model = OpenAiChatModel.builder()
.apiKey(apiKey)
.modelName(“gpt-4o-mini”)
.build();

var memory = MessageWindowChatMemory.withMaxMessages(10);
return AiServiceFactory.create(MemoryAiService.class, model, memory);
}
}

This setup maintains the last 10 exchanges, allowing continuity in conversation. Replace the AiService reference in your REST resource with this new MemoryAiService for persistent dialogue behavior.

Building a Document Summarizer

Beyond chat, let’s demonstrate a more specialized AI use case — summarizing documents. LangChain4j includes utilities for text chunking and summarization.

Create a new file, DocumentSummarizer.java:

package com.example;

import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiService;
import dev.langchain4j.service.SystemMessage;

@AiService
public interface DocumentSummarizer {

@SystemMessage(“You are an expert summarizer. Provide concise and factual summaries.”)
String summarize(String content);

static DocumentSummarizer create(String apiKey) {
var model = OpenAiChatModel.builder()
.apiKey(apiKey)
.modelName(“gpt-4o-mini”)
.build();

return AiServiceFactory.create(DocumentSummarizer.class, model);
}
}

You can then expose this summarizer as a REST endpoint:

@Path("/ai/summarize")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class SummarizerResource {
private final DocumentSummarizer summarizer = DocumentSummarizer.create(System.getenv(“OPENAI_API_KEY”));@POST
public Response summarize(DocumentInput input) {
String result = summarizer.summarize(input.text());
return Response.ok(new Summary(result)).build();
}public record DocumentInput(String text) {}
public record Summary(String summary) {}
}

This endpoint can be used for summarizing articles, user inputs, or even large internal documents.

Deploying and Optimizing Your Application

Quarkus provides multiple ways to deploy your app:

  • JVM Mode for standard deployments

  • Native Mode for instant startup and minimal memory usage

You can build a native image using GraalVM with a single command:

mvn package -Pnative

The resulting binary starts in milliseconds and is ideal for cloud environments like Kubernetes or serverless platforms.

To further optimize, you can:

  • Use Quarkus Dev Mode for hot reload: mvn quarkus:dev

  • Configure AI caching (e.g., store embeddings or responses in Redis)

  • Integrate vector stores for retrieval-augmented generation (RAG)

  • Secure endpoints with Quarkus Security extensions

Testing the AI Endpoints

You can write integration tests using Quarkus’s built-in test framework:

@QuarkusTest
public class AiResourceTest {
@Test
public void testChatEndpoint() {
given()
.contentType(“application/json”)
.body(“{\”message\”: \”What is LangChain4j?\”}”)
.when()
.post(“/ai/chat”)
.then()
.statusCode(200)
.body(“response”, notNullValue());
}
}

Run your tests using:

mvn test

Conclusion

Integrating AI into Java applications no longer requires complex inter-language bridges or external orchestration. With Quarkus and LangChain4j, Java developers can natively build intelligent, responsive, and context-aware systems using familiar programming patterns.

Quarkus brings performance, scalability, and developer productivity, while LangChain4j provides the AI brain—abstracting complex interactions with LLMs into elegant Java interfaces. Together, they enable:

  • Rapid prototyping of AI-enhanced microservices

  • Real-time conversational applications with memory

  • Context-driven summarization and document processing

  • On-prem or cloud-based model flexibility (via OpenAI, Ollama, etc.)

By adopting this stack, you can confidently build AI-infused enterprise-grade applications that maintain Java’s reliability and ecosystem maturity, while embracing the intelligence and flexibility of modern language models.

Whether you’re creating customer support assistants, intelligent report generators, or adaptive knowledge systems, Quarkus + LangChain4j forms a future-ready foundation for innovation.