InetAddress.getLocalHost() returns wrong result when hostname is 64 chars

Nishan picture Nishan · Feb 2, 2011 · Viewed 12.3k times · Source

I am using below code to print out hostname of a linux box using java 1.5

public static void main(String a[]) {
    System.out.println( InetAddress.getLocalHost().getCanonicalHostName() );
}

When I have hostname of the system a 64 char length string, the code just prints 'localhost.localdomain'. If my hostname length is less than 64, it prints out the hostname correctly. The max hostname length for the system is 64 (getconf HOST_NAME_MAX gives 64)

What could be wrong here? Could this be a bug (though, I am inclined to think problem is on my side)

Thanks for help!

Answer

e2-e4 picture e2-e4 · Feb 2, 2011

What is likely to happen on Linux is that InetAddress.getLocalHost() will return the loopback address (in 127/8, usually 127.0.0.1). Thus the name taken from the /etc/hosts file likely to be localhost.localdomain.

In order to get the correct address / host name, you can use the following code instead, that will list all IP address associated with a network interface (eth0 in my example), and we'll select the IPv4 one, that does not belong to the loopback class.

try {
    // Replace eth0 with your interface name
    NetworkInterface i = NetworkInterface.getByName("eth0");

    if (i != null) {

        Enumeration<InetAddress> iplist = i.getInetAddresses();

        InetAddress addr = null;

        while (iplist.hasMoreElements()) {
            InetAddress ad = iplist.nextElement();
            byte bs[] = ad.getAddress();
            if (bs.length == 4 && bs[0] != 127) {
                addr = ad;
                // You could also display the host name here, to 
                // see the whole list, and remove the break.
                break;
            }
        }

        if (addr != null) {
            System.out.println( addr.getCanonicalHostName() );
        }
    } catch (...) { ... }

You could change a bit the code to display all addresses, see the comments inside the code.

edit

You might want also to iterate over other NICs, as suggested by @rafalmag

instead of NetworkInterface.getByName("eth0") I suggest to iterate over NetworkInterface.getNetworkInterfaces()