United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4665037 InetAddress.getLocalHost() ambiguous on Linux systems
JDK-4665037 : InetAddress.getLocalHost() ambiguous on Linux systems

Details
Type:
Enhancement
Submit Date:
2002-04-09
Status:
Closed
Updated Date:
2006-12-08
Project Name:
JDK
Resolved Date:
2006-12-08
Component:
core-libs
OS:
linux
Sub-Component:
java.net
CPU:
x86
Priority:
P4
Resolution:
Won't Fix
Affected Versions:
1.4.0
Fixed Versions:

Related Reports

Sub Tasks

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

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
                                     
2003-09-30
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.
                                     
2004-08-24
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.
                                     
2006-12-08



Hardware and Software, Engineered to Work Together