[java] Recommended way to get hostname in Java

Although this topic has already been answered there's more to say.

First of all: Clearly we need some definitions here. The InetAddress.getLocalHost().getHostName() gives you the name of the host as seen from a network perspective. The problems with this approach are well documented in the other answers: it often requires a DNS lookup, it's ambiguous if the host has multiple network interfaces and it just plain fails sometimes (see below).

But on any OS there's another name as well. A name of the host that gets defined very early in the boot process, long before the network is initialized. Windows refers to this as computername, Linux calls it kernel hostname and Solaris uses the word nodename. I like best the word computername, so I'll use that word from now on.

Finding the computername

  • On Linux/Unix the computername is what you get from the C function gethostname(), or hostname command from shell or HOSTNAME environment variable in Bash-like shells.

  • On Windows the computername is what you get from environment variable COMPUTERNAME or Win32 GetComputerName function.

Java has no way of obtaining what I've defined as 'computername'. Sure, there are workarounds as described in other answers, like for Windows calling System.getenv("COMPUTERNAME"), but on Unix/Linux there's no good workaround without resorting to JNI/JNA or Runtime.exec(). If you don't mind a JNI/JNA solution then there's gethostname4j which is dead simple and very easy to use.

Let's move on with two examples, one from Linux and one from Solaris, which demonstrate how you can easily get into a situation where you cannot obtain the computername using standard Java methods.

Linux example

On a newly created system, where the host during installation has been named as 'chicago', we now change the so-called kernel hostname:

$ hostnamectl --static set-hostname dallas

Now the kernel hostname is 'dallas', as evident from the hostname command:

$ hostname
dallas

But we still have

$ cat /etc/hosts
127.0.0.1   localhost
127.0.0.1   chicago

There's no misconfiguration in this. It just means the host's networked name (or rather the name of the loopback interface) is different from the host's computername.

Now, try executing InetAddress.getLocalHost().getHostName() and it will throw java.net.UnknownHostException. You are basically stuck. There's no way to retrieve neither the value 'dallas' nor the value 'chicago'.

Solaris example

The example below is based on Solaris 11.3.

The host has deliberately been configured so that the loopback name <> nodename.

In other words we have:

$ svccfg -s system/identity:node listprop config
...
...
config/loopback             astring        chicago
config/nodename             astring        dallas

and the contents of /etc/hosts :

:1 chicago localhost
127.0.0.1 chicago localhost loghost

and the result of the hostname command would be:

$ hostname
dallas

Just like in the Linux example a call to InetAddress.getLocalHost().getHostName() will fail with

java.net.UnknownHostException: dallas:  dallas: node name or service name not known

Just like the Linux example you are now stuck. There's no way to retrieve neither the value 'dallas' nor the value 'chicago'.

When will you really struggle with this?

Very often you'll find that InetAddress.getLocalHost().getHostName() will indeed return a value which is equal to the computername. So there's no problem (except for the added overhead of name resolution).

The problem arises typically within PaaS environments where there's a difference between computername and the name of the loopback interface. For example people report problems in Amazon EC2.

Bug/RFE reports

A bit of searching reveals this RFE report : link1, link2. However, judging from the comments on that report the issue seems to have been largely misunderstood by the JDK team, so it is unlikely it will be addressed.

I like the comparison in the RFE to other programming languages.

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to network-programming

Difference between PACKETS and FRAMES socket connect() vs bind() How to read all of Inputstream in Server Socket JAVA C# An established connection was aborted by the software in your host machine Asynchronous Function Call in PHP TCP: can two different sockets share a port? trace a particular IP and port How is TeamViewer so fast? Recommended way to get hostname in Java Difference between TCP and UDP?

Examples related to environment-variables

Using Environment Variables with Vue.js Adding an .env file to React Project Is there any way to set environment variables in Visual Studio Code? Test process.env with Jest How to set environment variables in PyCharm? ARG or ENV, which one to use in this case? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? What is a good practice to check if an environmental variable exists or not? Passing bash variable to jq Tensorflow set CUDA_VISIBLE_DEVICES within jupyter

Examples related to hostname

How to get hostname from IP (Linux)? Can I map a hostname *and* a port with /etc/hosts? Get hostname of current request in node.js Express Recommended way to get hostname in Java Java SSL: how to disable hostname verification How can I use Python to get the system hostname? Python lookup hostname from IP with 1 second timeout How to extract the hostname portion of a URL in JavaScript How to store the hostname in a variable in a .bat file? how to find host name from IP with out login to the host