Here are common ways to resolve domain names in Java, from simplest to more advanced use cases.
Basic A/AAAA record lookup (IPv4/IPv6)
- Uses the system resolver and OS DNS settings.
- Returns all IPs (both IPv4 and IPv6 where available).
import java.net.InetAddress;
import java.net.UnknownHostException;
public class DnsLookup {
public static void main(String[] args) {
String host = "example.com";
try {
InetAddress[] addresses = InetAddress.getAllByName(host);
for (InetAddress addr : addresses) {
System.out.println(addr.getHostAddress());
}
} catch (UnknownHostException e) {
System.err.println("DNS lookup failed: " + e.getMessage());
}
}
}
Notes for InetAddress:
- No direct per-call timeout configuration (it relies on OS resolver timeouts).
- Caching is controlled by security properties:
-Dnetworkaddress.cache.ttl=60(seconds; -1 = forever; default often JVM-dependent)-Dnetworkaddress.cache.negative.ttl=10
- Prefer IPv6:
-Djava.net.preferIPv6Addresses=true
Asynchronous lookups
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CompletableFuture;
public class AsyncDns {
public static CompletableFuture<InetAddress[]> resolve(String host) {
return CompletableFuture.supplyAsync(() -> {
try {
return InetAddress.getAllByName(host);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
});
}
}
Reverse DNS (PTR)
- Basic: addr.getHostName() may trigger reverse lookup (can be slow or cached).
InetAddress addr = InetAddress.getByName("93.184.216.34");
String reverse = addr.getHostName(); // may do a PTR lookup
Query specific DNS record types (MX, TXT, SRV, PTR) or specific DNS servers
Option 1: JNDI DNS (built-in, configurable)
import javax.naming.directory.*;
import javax.naming.*;
import java.util.Hashtable;
public class JndiDns {
public static void main(String[] args) throws NamingException {
String domain = "example.com";
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
// Use specific DNS server(s) (optional)
env.put(Context.PROVIDER_URL, "dns://8.8.8.8 dns://1.1.1.1");
// Timeouts in milliseconds (optional)
env.put("com.sun.jndi.dns.timeout.initial", "2000");
env.put("com.sun.jndi.dns.timeout.retries", "1");
DirContext ctx = new InitialDirContext(env);
Attributes attrs = ctx.getAttributes(domain, new String[] {"MX", "TXT", "A"});
Attribute mx = attrs.get("MX");
if (mx != null) {
for (int i = 0; i < mx.size(); i++) System.out.println("MX: " + mx.get(i));
}
Attribute txt = attrs.get("TXT");
if (txt != null) {
for (int i = 0; i < txt.size(); i++) System.out.println("TXT: " + txt.get(i));
}
Attribute a = attrs.get("A");
if (a != null) {
for (int i = 0; i < a.size(); i++) System.out.println("A: " + a.get(i));
}
}
}
Notes:
- JNDI DNS supports MX, TXT, SRV, CNAME, PTR, etc.
- You can set specific DNS servers via PROVIDER_URL.
Option 2: Use a dedicated DNS library (e.g., dnsjava)
- Recommended for fine control, timeouts, EDNS, DNSSEC (if needed), or custom resolvers.
Maven Dependency:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>3.6.3</version>
<type>bundle</type>
</dependency>
Lookup A/AAAA with custom resolver and timeout:
import org.xbill.DNS.*;
public class DnsJavaExample {
public static void main(String[] args) throws Exception {
String domain = "example.com";
Resolver resolver = new SimpleResolver("8.8.8.8");
resolver.setTimeout(Duration.ofSeconds(2));
Name name = Name.fromString(domain + ".");
Record[] records = new Lookup(name, Type.A).run();
if (records != null) {
for (Record r : records) System.out.println(r.rdataToString());
}
}
}
SRV/TXT example:
import org.xbill.DNS.*;
Name srvName = Name.fromString("_sip._tcp.example.com.");
Record[] srv = new Lookup(srvName, Type.SRV).run();
if (srv != null) {
for (Record r : srv) System.out.println(r.rdataToString());
}
Name txtName = Name.fromString("example.com.");
Record[] txt = new Lookup(txtName, Type.TXT).run();
if (txt != null) {
for (Record r : txt) System.out.println(r.rdataToString());
}
Spring/Jakarta usage example (service component)
import org.springframework.stereotype.Service;
import java.net.InetAddress;
@Service
public class DnsService {
public String[] resolve(String host) {
try {
return java.util.Arrays.stream(InetAddress.getAllByName(host))
.map(InetAddress::getHostAddress)
.toArray(String[]::new);
} catch (Exception e) {
return new String[0];
}
}
}
Practical tips
- Retry logic: DNS failures are often transient. Consider simple retries with backoff when appropriate.
- Validate input: Ensure the host is a valid hostname to avoid unnecessary exceptions.
- Respect caching: Tune
networkaddress.cache.ttlfor your runtime environment to balance freshness and performance. - Split-horizon DNS: In containerized/cloud setups, behavior may differ between environments. Test where it runs.
- Don’t hardcode IPs unless necessary; prefer hostnames to benefit from DNS-based failover.
