JDK-4665037 : InetAddress.getLocalHost() ambiguous on Linux systems
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: linux
  • CPU: x86
  • Submitted: 2002-04-09
  • Updated: 2006-12-08
  • Resolved: 2006-12-08
Description
Name: nt126004			Date: 04/09/2002


FULL PRODUCT VERSION :
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

FULL OPERATING SYSTEM VERSION : Slackware 8.0

ADDITIONAL OPERATING SYSTEMS : RedHat, likely all other
linux systems

A DESCRIPTION OF THE PROBLEM :
Linux machines differentiate between the localhost
(127.0.0.1) address, which is used to simulate a network
connection, and the actual IP address of the machine.  In
almost all cases, the latter is more valuable for developing
a program - if a developer wants to simulate a connection,
he can hard code in an address of 127.0.0.1.  However, he
obviously cannot hard code the IP address for every computer
that is to run the program.  Also, one can't ask every user
of one's program to edit their /etc/hosts file to run the
program.  That kind of requirement is enough to make
developers look for another platform on which to run their
programs.  It would be much nicer behavior for Java to
return the actual IP address of the machine on which it is
run.

   1. Bug ID : 4424859 Reg-test CheckInetAddress.java Failing
      java :classes_net, Reg-test CheckInetAddress.java
Failing, State: Closed, fixed, Reported: Mar 12, 2001,
  Release reported against: ladybird
     
 http://developer.java.sun.com/developer/bugParade/bugs/4424859.html
- Feb 12, 2002

   2. Bug ID : 4460816 rmi connection error using linux server
      java :rmi, rmi connection error using linux server,
 State : Closed, not reproducible, Reported: May 18, 2001,
  Release reported against: 1.3
     
 ^C
- Feb 12, 2002

   3. Bug ID : 4435662 InetAddress.getLocalHost() gives
127.0.0.1 under RedHat with DHCP



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.  See bug reports 4435662 4424859 4460816
2.  Note that this is rather important networking behavior
that affects all linux systems, and it would be really cool
to have Java be truly platform-independent.
3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected results of getLocalHost: return IP address of machine
Actual results : return 127.0.0.1

This bug can be reproduced always.

----------------- BEGIN SOURCE --------------------
import java.net.*;

public class LocalHostTest {
	public static void main(String[] args) {
		try {
			System.out.println(InetAddress.getLocalHost());
		} catch (Exception e) { e.printStackTrace(); }
	}
}
(Review ID: 144338) 
======================================================================

Comments
EVALUATION It'd be more desirable to iterate all NICs and InetAddress bound to them by NetworkInterface class. Users will have more control by using NetworkInterface, too. So close this as will not fix.
08-12-2006

WORK AROUND If the host has a static IP address then the simple workaround is to correct /etc/hosts so that the hostname resolves to the correct address. Alternative, if the address is static and is registered in the name service (DNS for example) then change /etc/nsswitch.conf so that the name service is consulted prior to /etc/hosts. If the address is dynamic (DHCP or dial-up for example) and isn't registered (dynamically) in the name service then an alternative approach is to use java.net.NetworkInterface to enumerate all the local addresses. With the list of addresses the application can choose an appropriate local address -- ie: ignore any addreses that are loopback addresses (use InetAddress's isLoopbackAddress method), and additional use the java.net.preferIPv6Addresses system property so that an IPv4 or IPv6 local address is chosen as appropriate.
24-08-2004

EVALUATION On Linux the /etc/hosts file is normally configured depending on if there is a static or DHCP allocated address. If statically allocated then /etc/hosts file will typically look like :- # example 1 127.0.0.1 localhost.localdomain localhost 1.2.3.4 foo.domain.com foo If DHCP is used then it will typically look like :- # example 2 127.0.0.1 localhost.localdomain localhost foo Some distributions (including RedHat) appear to always configure /etc/hosts to map the hostname to the loopback address (even when the address is static), ie:- # example 3 127.0.0.1 localhost.localdomain localhost foo Assuming the above configurations the question is what does and what should InetAddress.getLocalHost() return. Assuming that /etc/nsswitch.conf has the default search ordering (files dns) then getLocalHost will return :- example 1: foo/1.2.3.4 example 2: foo/127.0.0.1 example 3: foo/127.0.0.1 If the DNS name service provider is used (sun.net.spi.nameservice.provider.1 system property set to "dns,sun") then the results are:- example 1: foo/1.2.3.4 or UHE example 2: foo/x.x.x.x or UHE example 3: foo/1.2.3.4 or UHE In example 2 "x.x.x.x" is the address assigned by DHCP and is returned if dynamic DNS has been used so that there is a mapping between foo and x.x.x.x in DNS. If foo is not registered in DNS then an UnknownHostException is throws in all cases. This RFE is about changing getLocalHost so that it tries to return a sensible host address rather than the loopback address. This should be examined for tiger to see which address is appropriate to return in each case. In the case of DHCP environments where dynamic DNS is used the requirement is clear - the appropriate address to return is the address known to DNS. However implementing this is awkward because the host resolver will typicall search /etc/hosts before it checks DNS and thus 127.0.0.1 will always be returned. In the case of a static IP address then /etc/hosts should be configured correctly and getLocalHost() should not attempt to work-around incorrectly configured hosts files. ###@###.### 2002-05-14 Further to the above note - on SLES 8, and perhaps other distributions, if /etc/sysconfig/network/dhcp is configured with DHCLIENT_SET_HOSTNAME="yes" then the DHCP client will set the hostname. With this configuration it means that InetAddress.getLocalHost() will return the expected result -- ie: ip address = address on eth0 or whatever the primary interface is, and the hostname = whatever the ip address resolves to via the name service. ###@###.### 2003-09-30
30-09-2003