How to Resolve a Domain Name in Java

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.ttl for 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.

How to Get Hostname and IP Address in Java

Here are the most common and reliable ways to get hostnames and IP addresses in Java (Java 21). Pick the approach that matches your runtime (desktop app, server app, behind proxy, etc.).

  1. Quick local host info
    • Good for simple cases, but can return 127.0.0.1 if your host isn’t configured in DNS/hosts.
    import java.net.InetAddress;
    
    public class LocalHostQuick {
        public static void main(String[] args) throws Exception {
            InetAddress local = InetAddress.getLocalHost();
            System.out.println("Host name: " + local.getHostName());
            System.out.println("Canonical host name: " + local.getCanonicalHostName());
            System.out.println("IP address: " + local.getHostAddress());
        }
    }
    
  2. Robust way: list network interfaces
    • Picks non-loopback, non-virtual, up interfaces; prefers IPv4 but supports IPv6.
    import java.net.Inet4Address;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.List;
    
    public class LocalAddresses {
        public static void main(String[] args) throws Exception {
            List<InetAddress> addresses = new ArrayList<>();
            for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
                NetworkInterface nif = ifaces.nextElement();
                if (!nif.isUp() || nif.isLoopback() || nif.isVirtual()) continue;
    
                for (Enumeration<InetAddress> addrs = nif.getInetAddresses(); addrs.hasMoreElements(); ) {
                    InetAddress addr = addrs.nextElement();
                    if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) continue; // skip 127.0.0.1, fe80::
                    addresses.add(addr);
                }
            }
    
            // Prefer IPv4 for display
            addresses.stream()
                     .sorted((a, b) -> Boolean.compare(b instanceof Inet4Address, a instanceof Inet4Address))
                     .forEach(a -> System.out.println(a.getHostAddress() + " (" + a.getHostName() + ")"));
        }
    }
    
  3. DNS lookup: resolve a hostname to IPs
    • Useful to get IPs for a remote host or reverse lookup a specific IP.
    import java.net.InetAddress;
    
    public class ResolveHost {
        public static void main(String[] args) throws Exception {
            String host = "example.com"; // replace with your host
            InetAddress[] all = InetAddress.getAllByName(host);
            for (InetAddress inet : all) {
                System.out.println(host + " -> " + inet.getHostAddress());
            }
    
            // Reverse lookup of a specific IP
            InetAddress ip = InetAddress.getByName("203.0.113.10"); // placeholder IP
            System.out.println(ip.getHostAddress() + " reverse -> " + ip.getCanonicalHostName());
        }
    }
    
  4. In a Spring MVC/Jakarta web app
    • Getting the client IP (taking proxies into account) and server info. Utility to extract client IP (checks common proxy headers, then falls back):
    import jakarta.servlet.http.HttpServletRequest;
    import java.util.List;
    
    public class IpUtils {
        private static final List<String> IP_HEADER_CANDIDATES = List.of(
            "X-Forwarded-For",
            "X-Real-IP",
            "CF-Connecting-IP",
            "Fastly-Client-Ip",
            "True-Client-Ip",
            "X-Cluster-Client-Ip",
            "Forwarded",
            "Forwarded-For"
        );
    
        public static String getClientIp(HttpServletRequest request) {
            for (String header : IP_HEADER_CANDIDATES) {
                String value = request.getHeader(header);
                if (value != null && !value.isBlank() && !"unknown".equalsIgnoreCase(value)) {
                    // X-Forwarded-For can contain a list: client, proxy1, proxy2...
                    String first = value.split(",")[0].trim();
                    if (!first.isBlank()) return first;
                }
            }
            return request.getRemoteAddr();
        }
    }
    

Controller example:

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.net.InetAddress;
import java.util.Map;

@RestController
public class NetInfoController {

    @GetMapping("/net-info")
    public Map<String, String> netInfo(HttpServletRequest request) throws Exception {
        String clientIp = IpUtils.getClientIp(request);

        // Server info via servlet and InetAddress
        String serverIp = request.getLocalAddr();     // or request.getServerName()
        String serverHostName = InetAddress.getLocalHost().getHostName();

        return Map.of(
            "clientIp", clientIp,
            "serverIp", serverIp,
            "serverHostName", serverHostName
        );
    }
}

Notes and tips

  • getLocalHost may return 127.0.0.1 if your machine’s hostname isn’t resolvable. Enumerating NetworkInterface is more reliable.
  • For containers/Kubernetes, you may prefer:
    • The interface enumeration approach, or
    • Reading an environment variable like HOSTNAME (if set by the platform).
  • Reverse DNS (getCanonicalHostName) depends on network/DNS config and may be slow; cache if needed.
  • Always handle exceptions: UnknownHostException, SocketException.
  • When behind proxies/load balancers, only trust client-IP headers if your infrastructure sanitizes them; otherwise they can be spoofed.

How to Build a Simple Web Server in Java

Building a simple web server in Java involves creating a server socket to listen on a specific port, accepting client requests, and sending responses back to the client. Below is a basic example of building a simple HTTP server in Java.

Example Code

package org.kodejava.net;

import java.io.*;
import java.net.*;

public class SimpleWebServer {
    public static void main(String[] args) {
        int port = 8080; // Port number the server will listen on

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("Server is listening on port " + port);

            while (true) {
                // Accept incoming client connections
                Socket clientSocket = serverSocket.accept();

                // Create a new thread to handle the request
                new Thread(() -> handleClientRequest(clientSocket)).start();
            }
        } catch (IOException e) {
            System.err.println("Server exception: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void handleClientRequest(Socket clientSocket) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
             PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {

            // Read the HTTP request from the client
            String requestLine = in.readLine();
            System.out.println("Client request: " + requestLine);

            // Read and discard the rest of the request headers
            while (in.ready() && in.readLine() != null);

            // Build a basic HTTP response
            String responseBody = "<html><body><h1>Welcome to Simple Java Web Server</h1></body></html>";
            String response = "HTTP/1.1 200 OK\r\n" +
                              "Content-Type: text/html\r\n" +
                              "Content-Length: " + responseBody.length() + "\r\n" +
                              "\r\n" +
                              responseBody;

            // Send the HTTP response to the client
            out.write(response);
            out.flush();

        } catch (IOException e) {
            System.err.println("Client handling exception: " + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                System.err.println("Failed to close client socket: " + e.getMessage());
            }
        }
    }
}

Steps to Run the Server

  1. Compile the Code
    Save the file as SimpleWebServer.java and compile it:

    javac SimpleWebServer.java
    
  2. Run the Server
    Execute the program:

    java SimpleWebServer
    
  3. Access the Server
    Open a web browser and navigate to http://localhost:808. You should see the message:
    Welcome to Simple Java Web Server.

Key Concepts

  1. ServerSocket:
    The ServerSocket class is used to listen on a specific port for incoming connections.
  2. Socket:
    Represents the client’s connection. You can use the Socket object to read the request and send the response.
  3. HTTP Protocol:
    The server follows a basic structure of HTTP responses:

    • First the status line (e.g., HTTP/1.1 200 OK).
    • Then the headers (e.g., Content-Type and Content-Length).
    • Finally, the response body.
  4. Multithreading:
    Each client connection is handled on a separate thread to allow the server to process multiple requests simultaneously.

Notes

  • Error Handling: Additional error handling should be implemented in production-level servers.
  • Performance: For larger servers, consider using established frameworks like Spring Boot or Jakarta EE.
  • Security: This is a basic example and does not address security concerns like HTTPS, request validation, etc.

How to Check If a Date Is Weekend in Java

Here are simple and reliable ways to check whether a date falls on a weekend in Java. Prefer the modern java.time API (Java 8+), which is clearer and thread-safe.

  • Using LocalDate (recommended)
import java.time.DayOfWeek;
import java.time.LocalDate;

public class WeekendChecker {
    public static boolean isWeekend(LocalDate date) {
        DayOfWeek dow = date.getDayOfWeek();
        return dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY;
    }

    public static void main(String[] args) {
        System.out.println(isWeekend(LocalDate.now())); // true or false
    }
}
  • With time zones (e.g., when you start from an Instant)
import java.time.*;

public class WeekendCheckerTZ {
    public static boolean isWeekend(Instant instant, ZoneId zone) {
        DayOfWeek dow = instant.atZone(zone).getDayOfWeek();
        return dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY;
    }

    public static void main(String[] args) {
        boolean weekendInNY = isWeekend(Instant.now(), ZoneId.of("America/New_York"));
        System.out.println(weekendInNY);
    }
}
  • If you still use the legacy Calendar API
import java.util.Calendar;

public class WeekendCheckerLegacy {
    public static boolean isWeekend(Calendar cal) {
        int dow = cal.get(Calendar.DAY_OF_WEEK);
        return dow == Calendar.SATURDAY || dow == Calendar.SUNDAY;
    }
}
  • Configurable “weekend” definition (some regions consider Friday/Saturday)
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.EnumSet;
import java.util.Set;

public class ConfigurableWeekend {
    private static final Set<DayOfWeek> DEFAULT_WEEKEND = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);

    public static boolean isWeekend(LocalDate date, Set<DayOfWeek> weekendDays) {
        return weekendDays.contains(date.getDayOfWeek());
    }

    public static void main(String[] args) {
        System.out.println(isWeekend(LocalDate.now(), DEFAULT_WEEKEND));
        // Example for Fri/Sat weekend:
        Set<DayOfWeek> friSatWeekend = EnumSet.of(DayOfWeek.FRIDAY, DayOfWeek.SATURDAY);
        System.out.println(isWeekend(LocalDate.now(), friSatWeekend));
    }
}

Notes:

  • Use java.time classes (LocalDate, ZonedDateTime, DayOfWeek) for new code.
  • If you have a timestamp without a zone (Instant), convert with a ZoneId before checking the day of the week.

How to Convert Between Date and LocalDateTime

In Java, you can convert between java.util.Date and java.time.LocalDateTime using the java.time API introduced in Java 8. Here’s how you can perform the conversions:


1. Converting Date to LocalDateTime

You need to use java.time.Instant and java.time.ZoneId to make this conversion. Here’s the process:

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateToLocalDateTimeExample {
    public static void main(String[] args) {
        // Create a Date object
        Date date = new Date();

        // Convert Date to LocalDateTime
        LocalDateTime localDateTime = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();

        System.out.println("Date: " + date);
        System.out.println("LocalDateTime: " + localDateTime);
    }
}

2. Converting LocalDateTime to Date

To convert back from LocalDateTime to Date, again you will make use of Instant and ZoneId.

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class LocalDateTimeToDateExample {
    public static void main(String[] args) {
        // Create a LocalDateTime object
        LocalDateTime localDateTime = LocalDateTime.now();

        // Convert LocalDateTime to Date
        Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

        System.out.println("LocalDateTime: " + localDateTime);
        System.out.println("Date: " + date);
    }
}

Explanation:

  1. Date to LocalDateTime:
    • Date.toInstant() converts the Date object into an Instant (a specific point in time).
    • .atZone(ZoneId.systemDefault()) adjusts the instant to your system’s default time zone.
    • .toLocalDateTime() converts the zoned date-time to a LocalDateTime.
  2. LocalDateTime to Date:
    • .atZone(ZoneId.systemDefault()) converts a LocalDateTime into a ZonedDateTime.
    • ZonedDateTime.toInstant() gets an Instant for the given date and time in the local zone.
    • Date.from(Instant) creates a Date object from the Instant.

By using these conversions, you can easily switch between the old java.util.Date and the modern java.time.LocalDateTime API.