64

I was wondering if there is a way to get the computer name in Java? I have seen several answers that feature java.net.InetAddress. However I was wondering if there is a way that does not use the network?

(As a side question, is the computer name only a network thing anyway, so therefore has to be done this way??)

dann.dev
  • 2,406
  • 3
  • 20
  • 32
  • 1
    Try http://stackoverflow.com/questions/473446/java-current-machine-name-and-logged-in-user – Jonathan Spooner Oct 25 '11 at 00:54
  • You're only really using the loopback interface, aka `localhost` – Jonathan Spooner Oct 25 '11 at 00:57
  • 3
    Naming a computer that's not on a network is like naming a cat - except instead of it ignoring you when you call it, nobody is calling it. – Paul Tomblin Oct 25 '11 at 00:58
  • 1
    @JonathanSpooner - Erm, our production machines have their real names in /etc/hosts for this reason. I don't get back 'localhost' ;) – Brian Roach Oct 25 '11 at 01:04
  • @BrianRoach `localhost` is just another name for the loopback interface aka 127.0.0.1 /etc/hosts maps this address to localhost.localdomain aka `localhost` – Jonathan Spooner Oct 25 '11 at 01:24
  • @JonathanSpooner Not if you configure it otherwise. The code snippit in my answer below does *not* produce the name 'localhost' on our production machines; it produces the FQDN we have assigned to the machine. We do this specifically so we are able to get it for logging, etc. There's no magic involved with DNS, you can configure it however you want. – Brian Roach Oct 25 '11 at 01:28
  • @BrianRoach Yes you can change the name of your loopback interface – Jonathan Spooner Oct 25 '11 at 01:30
  • @BrianRoach Forgive me, I was only reassuring the OP that he was not really using the network but only the loopback interface in this instance. – Jonathan Spooner Oct 25 '11 at 01:41
  • Thanks guys, and I if I ever have a Cat I will name it localhost... – dann.dev Oct 25 '11 at 01:49
  • 4
    Hell no - you name it `5`. Subsequent cats should be named `5e` and `6` ;) (Though I suppose you could name one `TenBaseTee` if you're old school) – Brian Roach Oct 25 '11 at 01:55
  • [Bast](https://simple.wikipedia.org/wiki/Bast) is a good name for a cat. – Agi Hammerthief Aug 14 '18 at 07:25

3 Answers3

103

The computer "name" is resolved from the IP address by the underlying DNS (Domain Name System) library of the OS. There's no universal concept of a computer name across OSes, but DNS is generally available. If the computer name hasn't been configured so DNS can resolve it, it isn't available.

import java.net.InetAddress;
import java.net.UnknownHostException;

String hostname = "Unknown";

try
{
    InetAddress addr;
    addr = InetAddress.getLocalHost();
    hostname = addr.getHostName();
}
catch (UnknownHostException ex)
{
    System.out.println("Hostname can not be resolved");
}
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • 37
    I'm wondering how this can be the accepted answer when OP asks for a solution : "a way that does not use the network?" – peterh Nov 29 '13 at 15:10
  • 1
    On Mac OS X, this solution may provide a hostname that is different, depending if the computer is connected to the network or not – Octave Dec 29 '16 at 09:53
66

I agree with peterh's answer, so for those of you who like to copy and paste instead of 60 more seconds of Googling:

private String getComputerName()
{
    Map<String, String> env = System.getenv();
    if (env.containsKey("COMPUTERNAME"))
        return env.get("COMPUTERNAME");
    else if (env.containsKey("HOSTNAME"))
        return env.get("HOSTNAME");
    else
        return "Unknown Computer";
}

I have tested this in Windows 7 and it works. If peterh was right the else if should take care of Mac and Linux. Maybe someone can test this? You could also implement Brian Roach's answer inside the else if you wanted extra robustness.

Tot Zam
  • 8,406
  • 10
  • 51
  • 76
Javanator
  • 871
  • 7
  • 10
  • 2
    For Ubuntu 14.04, at least, this won't work. The only environment variable where the computer's name appears is the `SESSION_MANAGER` variable. But you need to parse it because it looks like this: `local/<>:@/tmp/.ICE-unix/2131,unix/<>:/tmp/.ICE-unix/2131` – Sharcoux Oct 08 '16 at 11:25
  • if you issue "export HOSTNAME" then the environment variable will be passed on to subtasks. – neuhaus Oct 11 '16 at 16:07
  • Peterh here. Thanks for this implementation. Wrt to Unix/Linux and Sharcoux's comment I've updated [my answer](http://stackoverflow.com/a/17956000/1504556). – peterh Nov 06 '16 at 20:57
  • As an alternative on Ubuntu, the output of the hostname command can be captured... – snorbi Jan 02 '17 at 13:33
  • 3
    I'd rather make the function `public static` – bct Jan 26 '17 at 04:35
  • Every other "answer" should be deleted. – Ojonugwa Jude Ochalifu Apr 03 '18 at 09:22
  • I can confirm `HOSTNAME` is working on RHEL. – fuggi Feb 12 '20 at 07:26
55

I'm not so thrilled about the InetAddress.getLocalHost().getHostName() solution that you can find so many places on the Internet and indeed also here. That method will get you the hostname as seen from a network perspective. I can see two problems with this:

  1. What if the host has multiple network interfaces ? The host may be known on the network by multiple names. The one returned by said method is indeterminate afaik.

  2. What if the host is not connected to any network and has no network interfaces ?

All OS'es that I know of have the concept of naming a node/host irrespective of network. Sad that Java cannot return this in an easy way. This would be the environment variable COMPUTERNAME on all versions of Windows and the environment variable HOSTNAME on Unix/Linux/MacOS (or alternatively the output from host command hostname if the HOSTNAME environment variable is not available as is the case in old shells like Bourne and Korn).

I would write a method that would retrieve (depending on OS) those OS vars and only as a last resort use the InetAddress.getLocalHost().getHostName() method. But that's just me.

UPDATE (Unices)

As others have pointed out the HOSTNAME environment variable is typically not available to a Java application on Unix/Linux as it is not exported by default. Hence not a reliable method unless you are in control of the clients. This really sucks. Why isn't there a standard property with this information?

Alas, as far as I can see the only reliable way on Unix/Linux would be to make a JNI call to gethostname() or to use Runtime.exec() to capture the output from the hostname command. I don't particularly like any of these ideas but if anyone has a better idea I'm all ears. (update: I recently came across gethostname4j which seems to be the answer to my prayers).

Long read

I've created a long explanation in another answer on another post. In particular you may want to read it because it attempts to establish some terminology, gives concrete examples of when the InetAddress.getLocalHost().getHostName() solution will fail, and points to the only safe solution that I know of currently, namely gethostname4j.

It's sad that Java doesn't provide a method for obtaining the computername. Vote for JDK-8169296 if you are able to.

Community
  • 1
  • 1
peterh
  • 18,404
  • 12
  • 87
  • 115
  • I'm loving the gethostname4j solution! I tried editing the /etc/hosts file as others have suggested. Don't know why, but it didn't fix the problem for me. gethostname4j returns the same name that I was getting from Inet but much quicker, especially on mac. – mbreck Mar 10 '21 at 16:47
  • I'm quite liking your library too! Thank you for developping such a nice solution for the community. – Barracuda May 31 '22 at 15:36