85

With the following code:

try {
  System.out.println(new Date());
  InetAddress hostName = InetAddress.getLocalHost();
  System.out.println(new Date());
} catch (UnknownHostException e) {
  e.printStackTrace();
}

I get this output:

Thu Oct 22 20:58:22 BST 2015
Thu Oct 22 20:58:52 BST 2015

In other words 30 seconds to execute. Machine is 2015 Macbook Pro with Java 1.8.0_60.

Why does this take so long?

imrichardcole
  • 4,633
  • 3
  • 23
  • 45

5 Answers5

169

The issue can be solved by adding the following to /etc/hosts (assuming output of hostname command is my-macbook:

127.0.0.1   my-macbook
::1         my-macbook

This returns the time to something more suitable (< 1 second)

DimaSan
  • 12,264
  • 11
  • 65
  • 75
imrichardcole
  • 4,633
  • 3
  • 23
  • 45
  • 3
    It works, and this helped me when troubleshooting :-) I added an answer for an issue on osx sierra [here](http://stackoverflow.com/questions/39636792/sbt-test-extremely-slow-on-macos-sierra/39698914#39698914) and I mentioned your solution also [on this blog post](https://thoeni.io/post/macos-sierra-java/) – thoeni Sep 28 '16 at 12:08
  • 2
    Sometimes the name is not that obvious, to fint it out first run hostname command and then modify your /etc/hosts file, in my case it the name was macbooks-MacBook-Air as you can see 127.0.0.1 localhost macbooks-MacBook-Air.local ::1 localhost macbooks-MacBook-Air.local – Vladimir Stazhilov Sep 11 '17 at 10:20
  • Yes it works, but you may want to keep the localhost hostname as suggested by Octavian R. in the answer bellow. – Antoine Martin Mar 08 '19 at 13:18
38

This problem appears on MacOS Sierra using Java8, updates equals or bigger than 60 (jdk1.8.0_60.jdk, jdk1.8.0_77.jdk, etc).

The solution can be found here: https://github.com/thoeni/inetTester.

This is the content of my /etc/hosts file:

127.0.0.1   localhost mac.local
::1         localhost mac.local

In my case, mac is my computer name.

Octavian R.
  • 1,231
  • 8
  • 12
11

The above answer works on my mac, you can try it like this:

step 1, download inetTester.jar from thoeni/inetTester

step 2, run it on your mac. here is the result on my mac:

$ java -jar ./inetTester.jar
Calling the hostname resolution method...
Method called, hostname MacBook-Pro.local, elapsed time: 5009 (ms)

it takes 5s to run the test, and it shows the hostname of my mac.

step 3, modify the /etc/hosts:

127.0.0.1   MacBook-Pro.local
::1         MacBook-Pro.local

the host is what shows in step 2. and after this, run the test again:

$ java -jar ./inetTester.jar
Calling the hostname resolution method...
Method called, hostname MacBook-Pro.local, elapsed time: 6 (ms)

yeah, it comes with only 6ms.

shilaimuslm
  • 2,005
  • 1
  • 10
  • 11
  • Amazingly this issue still exists on macOS Monterey 12.4. Adding `.local` to /etc/hosts saves about half a second to call `InetAddress.getLocalHost()` – pyb Jul 12 '22 at 13:10
8

I suspect the delay here was due to a failed attempt at DNS resolution. Perhaps your DNS servers were not configured correctly. The 30 seconds probably represents the timeout on the DNS resolution.

The reason your solution improved the speed is that adding the entry to the hosts file allowed the hostname to be resolved locally and thus skip the attempt to resolve the hostname against an actual (remote) DNS server.

EDIT: You may wonder why this method does any host resolution at all. Apparently, it is part of an anti-spoofing mechanism built in to the Java networking library. See the accepted answer of this post for more details: InetAddress.getCanonicalHostName() returns IP instead of Hostname

bischoje
  • 197
  • 1
  • 8
3

On a MacBook Pro with Java 1.8.0_92 and 1.80_112 this problem is still existing, the call to InetAddress.getLocalhost() needs > 5 seconds. The solution with the modified /etc/hosts does not work. Only switching back to Java 1.8.0_051 solves this problem.