Teaching Your Java App DNS: AI-Driven Lookups with Quarkus and LangChain4j
Build a smart DNS assistant using Quarkus, LangChain4j, and a local LLM.
What if you could ask your Java app, “What are the MX records for gmail.com?” and get a precise, AI-generated answer in seconds, without ever leaving your terminal?
That’s exactly what we’re building in this tutorial.
You’ll learn how to combine Quarkus, Langchain4j, and a local Large Language Model (LLM) to give your Java application the power to perform real-time DNS lookups. Using simple annotations and a clean design, you’ll empower your AI agent to call real-world tools, like querying A, MX, and CNAME records, then respond in natural language.
Let’s wire up some artificial intelligence to one of the internet’s oldest protocols.
Prerequisites
Make sure you have the following installed before we start:
JDK 17 or later
Apache Maven 3.8+
Podman (or Docker if you want to use Dev Services)
You might also want the Quarkus CLI or start your project via https://code.quarkus.io
Laying the Foundation: Quarkus Project Setup
Let’s start by generating a Quarkus project with the required extensions. You can do this via the CLI:
quarkus create app org.acme:dns-ai --no-code
cd dns-ai
quarkus extension add quarkus-langchain4j-ollama quarkus-rest-jackson
cd dns-ai
We’ll manually add the DNS library. In your pom.xml
, add the following:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>3.5.3</version>
</dependency>
Now configure some application properties for local llm inference:
# src/main/resources/application.properties
quarkus.langchain4j.ollama.timeout=60s
quarkus.langchain4j.ollama.model.name=llama3.2:latest
You’re now ready to wire up the brains.
Building the DNS Tool: Give Your AI Real Powers
Next, we’ll create a simple Java class with annotated methods that the LLM can call. src/main/java/org/acme/DnsTools.java
package org.acme;
package org.acme;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import dev.langchain4j.agent.tool.Tool;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class DnsTools {
@Tool("Get the A records for a given domain")
public List<String> getARecords(String domain) {
return getRecords(domain, Type.A);
}
@Tool("Get the MX records for a given domain")
public List<String> getMxRecords(String domain) {
return getRecords(domain, Type.MX);
}
@Tool("Get the CNAME records for a given domain")
public List<String> getCnameRecords(String domain) {
return getRecords(domain, Type.CNAME);
}
private List<String> getRecords(String domain, int type) {
try {
Lookup lookup = new Lookup(domain, type);
Record[] records = lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
return Arrays.stream(records)
.map(Record::rdataToString)
.collect(Collectors.toList());
}
} catch (TextParseException e) {
e.printStackTrace();
}
return List.of();
}
}
Let’s unpack what’s happening here.
Each public method is annotated with
@Tool
, which makes it discoverable by the AI agent.The
description
in the annotation helps the LLM understand when to call which tool.dnsjava
handles the actual DNS queries, making your app more robust than trying to shell out tonslookup
.
This class is now your AI's gateway to real-world network data.
AI Service Interface: Giving Instructions to Your Agent
We’ll now wire up a service that connects Langchain4j to your DNS tools. Create the class src/main/java/org/acme/DnsAiService.java:
package org.acme;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import io.quarkiverse.langchain4j.RegisterAiService;
import io.quarkiverse.langchain4j.ToolBox;
@RegisterAiService
public interface DnsAiService {
@SystemMessage("You are a DNS expert. Use the available tools to find A, MX, and CNAME records for the given domain and provide a summary to the user.")
@ToolBox(DnsTools.class)
String getDnsInfo(@UserMessage String domain);
}
This interface is auto-implemented by Langchain4j. A few key annotations to note:
@RegisterAiService
connects this AI agent to our DNS toolset.@SystemMessage
sets the context and role of the AI (you’re a DNS expert, not a vague chatbot).@UserMessage
marks the incoming query.The
@ToolBox(DnsTools.class)
annotation specifies which tool to use, allowing the model to call the methods
Quarkus takes care of dependency injection and bootstrapping. No extra config needed.
Expose the Power: REST Endpoint to Trigger the AI
Finally, let’s create a REST API that passes user input to the AI. Create src/main/java/org/acme/DnsResource.java
package org.acme;
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
@Path("/dns")
public class DnsResource {
@Inject
DnsAiService dnsAiService;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getDnsInfoForDomain(@QueryParam("domain") String domain) {
return dnsAiService.getDnsInfo(domain);
}
}
This simple endpoint takes a domain as a query parameter and returns a natural language response from the AI.
It’s magic with only a few lines of code.
Run It: Putting Your AI DNS Expert to Work
Start everything up with:
quarkus dev
Then hit the endpoint:
curl "http://localhost:8080/dns?domain=google.com"
You might see something like:
For the domain `google.com`, I found the following records:
* **A Records:**
* One A record pointing to the IP address `142.250.185.174`.
* **MX Records:**
* No MX records were found for the domain.
* **CNAME Records:**
* No CNAME records were found for the domain.
Or the AI might summarize slightly differently depending on the model’s style. Either way, it’s using your DnsTools
behind the scenes.
Where to Go Next
You’ve now built a fully working AI-enhanced Java app with Quarkus that performs real-time DNS lookups through tool calling. Want to go further?
Try adding:
A
TXT
record lookupSupport for querying NS or SOA records
LLM tool chaining (e.g. identify domain from user question, then lookup)
A chat-based UI with Qute and WebSockets
And if you're curious how Langchain4j works under the hood or want to plug in external APIs, the official guide is a great place to dig deeper: Langchain4j Quarkus Extension
Final Thoughts
This isn’t just a toy project. It demonstrates how LLMs can augment your backend applications with dynamic, explainable actions and bridging static APIs with real-time, conversational power.
You didn’t just write a DNS tool. You taught your AI agent to reason, act, and respond.
Next time someone asks, “What can Java do with AI?”—you’ve got the curl command to prove it.
Hi,
I tried to follow your tutorial, and it seems you are missing @ApplicationScoped annotation for DnsTools class. It will return java.lang.IllegalStateException: Unknown tool: error if no annotation added.