How do I get the local hostname if unresolvable through DNS in Java?

Shawn D. picture Shawn D. · May 18, 2011 · Viewed 24.7k times · Source

This sounds like something that should have been asked before, and it has sort of, but I'm looking to get the local hostname and IP addresses of a machine even when it is not resolvable through DNS (in Java).

I can get the local IP addresses without resolution by iterating through NetworkInterfaces.getNetworkInterfaces().

Any answers to this question I've found indicate to use getLocalHost()

InetAddress localhost = java.net.InetAddress.getLocalHost();
hostName = localhost.getHostName();

but this throws an UnknownHostException if the hostname isn't resolvable through DNS.

Is there no way to get the local hostname without a DNS lookup happening behind the scenes?

edit: the IP address retrieved is 10.4.168.23 The exception is java.net.UnknownHostException: cms1.companyname.com: cms1.companyname.com (hostname changed for pseudo-anonymity), and the hosts file does not contain the hostname. But it does know its hostname, so I'm not sure why I can't get it without an exception being thrown.

Answer

peterh picture peterh · Jul 31, 2013

Yes, there should be a way in Java to get the hostname without resorting to name service lookups but unfortunately there isn't.

However, you can do something like this:

if (System.getProperty("os.name").startsWith("Windows")) {
    // Windows will always set the 'COMPUTERNAME' variable
    return System.getenv("COMPUTERNAME");
} else {
    // If it is not Windows then it is most likely a Unix-like operating system
    // such as Solaris, AIX, HP-UX, Linux or MacOS.

    // Most modern shells (such as Bash or derivatives) sets the 
    // HOSTNAME variable so lets try that first.
    String hostname = System.getenv("HOSTNAME");
    if (hostname != null) {
       return hostname;
    } else {

       // If the above returns null *and* the OS is Unix-like
       // then you can try an exec() and read the output from the 
       // 'hostname' command which exist on all types of Unix/Linux.

       // If you are an OS other than Unix/Linux then you would have 
       // to do something else. For example on OpenVMS you would find 
       // it like this from the shell:  F$GETSYI("NODENAME") 
       // which you would probably also have to find from within Java 
       // via an exec() call.

       // If you are on zOS then who knows ??

       // etc, etc
    }
}

and that will get you 100% what you want on the traditional Sun JDK platforms (Windows, Solaris, Linux) but becomes less easy if your OS is more excotic (from a Java perspective). See the comments in the code example.

I wish there was a better way.