Search code examples
javahostnamefqdn

Why java getHostName gives the FQDN?


Why sometimes, Java inetAddress.getHostName(); gives the fully qualified domain name and sometimes only hostname without domain? Is there something which can be tweaked at system level to get either fqdn or hostname only by calling that method. I know inetAddress.getCanonicalHostName() is there, but I want to know if we can play around getHostName().


Solution

  • Why does java getHostName sometime gives the FQDN and sometimes not?

    Short answer: because it depends on information provided by the OS.


    In Java 11, the hostname returned by InetAddress is obtained by using the JVM's DNS resolver to perform a reverse lookup on the IP address.

    The default behavior for the JVM's DNS resolver is to delegate to the OS-provided local DNS resolver. It is also possible to configure Java to use a simple builtin resolver that gets all name server data from a file; search the Java 9 release notes for the description of the "jdk.net.hosts.file" property.

    (Prior to Java 9, the implementation different but (AFAIK) the default behavior was to use the OS-provided name resolution.)


    I am looking at it on RHEL

    (This not really a "programming" question anymore, but here goes ...)

    On Linux the reverse lookup turns into a call to getnameinfo(3) which makes the resolver call; refer to the Linux manual entry for the full details. The resolver behavior depends on the "/etc/nsswitch.conf" file: specifically the "hosts" line. For example on my (Ubuntu) system it says:

    hosts:  files mdns4_minimal [NOTFOUND=return] dns myhostname
    

    This says to try the lookup in the following places:

    1. "files" means the "/etc/hosts" file.
    2. "mdns4_minimal" is a flavor of mDNS (multicast DNS) service; see https://askubuntu.com/a/853284/566610
    3. "dns" is classical centralized DNS
    4. "myhostname" is a fallback that uses the system information typically configured by the hostname command.

    So, if I have added an entry for my host's IP address to my "/etc/hosts" file, then the first name in that entry will be what getHostname returns. It could be a simple name or a FQDN, depending on what the file says. Here's an example:

    192.168.1.1    bogsnorkel.example.com bogsnorkel
    

    (With my nsswitch.conf settings as above, and if my primary IP was 192.168.1.1, getHostname() would return "bogsnorkel.example.com". But if the unqualified name "bogsnorkel" was first, it would return that instead.)

    But if there isn't an "/etc/hosts" entry, then next step will be to lookup in mDNS or else DNS. If the IP has been registered with mDNS / DNS, then you should get an FQDN.

    Finally, the fallback will be whatever was set using hostname.


    Stepping back: if you are looking for a way to ensure that your application always gets an FQDN from inetAddress.getHostName() irrespective of OS-level configurations, etc, you are probably out of luck:

    • It would be better to make your application insensitive to that.
    • If that is not possible:
      1. Have your application check that the hostname is acceptable on startup and "bail out" if it isn't.
      2. Redirect the user to OS instructions for configuring an FQDN
      3. Maybe ... provide an option or config parameter for the case where the (non-privileged) user cannot fix what the OS is returning.