InetAddress.getCanonicalHostName() does not return FQDN on SuSE Linux 8.0
FULL PRODUCT VERSION :
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)
FULL OPERATING SYSTEM VERSION :
Linux swlinux 2.4.18-4GB #1 Wed May 29 15:47:24 UTC 2002 i686
customer 8.0 (i386)
VERSION = 8.0
A DESCRIPTION OF THE PROBLEM :
InetAddress.getCanonicalHostName() is not returning the fully-qualified domain name. Instead, it is returning the IP address. We really need the fully-qualified domain name, and this is the only routine documented to return
it. The code only fails on SuSE 8.0. We're sucessfully running in on Windows 2000, several versions of Red Hat Linux, and several versions of HP-UX.
EXPECTED VERSUS ACTUAL BEHAVIOR :
The output of my test program on Red Hat Linux 7.1
My name is: kothay.fc. customer .com
My FQDN is: kothay.fc. customer .com
My IP is: 22.214.171.124
InetAddress: kothay.fc. customer .com/126.96.36.199
The output of my test program on SuSE 8.0 (actual results):
My name is: swlinux
My FQDN is: 188.8.131.52
My IP is: 184.108.40.206
ERROR MESSAGES/STACK TRACES THAT OCCUR :
There are no error messages.
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class hostnameBug
public static void main(String args)
InetAddress ia = InetAddress.getLocalHost();
System.out.println("My name is: " + ia.getHostName());
System.out.println("My FQDN is: " + ia.getCanonicalHostName());
System.out.println(" My IP is: " + ia.getHostAddress());
System.out.println("\nInetAddress: " + ia);
catch (UnknownHostException e)
System.out.println("oops, couldn't get localhost");
---------- END SOURCE ----------
(Review ID: 166641)
InetAddress.getCanonicalHostName() method is specified to do best effort. But depending on the system configuration, we may not be able to return FQDN.
In order for us to further the investigation, please provide us with your system configuration files, such as the hosts, your host name search path, your nslookup results on ptr record for your IP address.
In the meantime, here's several things you can check:
1. Check your nsswitch.conf file or equivalent. On linux, you can use linuxconf to check your hostname search path. Does it contain DNS? if not, that could be the problem, 'cause usually hosts file or nis doesn't contain FQDN/IP mappings.
If your host name search path do contain DNS, AND it precedes either hosts or other name lookup mechanisms, try the following:
2. Do a nslookup. issue a ptr command for your ip address 220.127.116.11. does it return a FQDN? if it does, your DNS server does contain an A record for your machine. otherwise it doesn't. In case it doesn't, you will have to additional things to configure the FQDN/IP mapping, such as add appropriate entries to the DNS database.
If your name search path does contain DNS, but it's not the first in the search path. Furthermore, you can't change the search sequence on your system, you can do the following:
3. Specify the JNDI DNS service provider to bypass the default system name service provider. Use the properties defined at http://java.sun.com/j2se/1.4/docs/guide/net/properties.html and look for JNDI DNS service provider settings.
In glibc2.2.4 the IPv6 support in libnss_dns.so was moved to
to a libnss_dns6.so. This means that IPv6-enabled applications
using getaddrinfo/getnameinfo need /etc/nsswitch.conf changed to
search the hosts database using "dns6" instead of "dns". In
order words, "dns" is IPv4 only, and "dns6" is IPv4 and IPv6.
SuSE 8.0 ships with IPv6 compiled into the kernel and glibc2.2.5.
However it ships with /etc/nsswitch.conf configured to use "dns".
This means that IPv6 lookups and reverse lookups aren't possible
with an out-of-the-box SuSE 8.0 installation. Hopefully SuSE will
J2SE 1.4.x is IPv6-enabled. When run on a machine with IPv6
enabled java.net.InetAddress's default name service provider
will use getaddrinfo/getnameinfo to do lookups and reverse
lookups resp. Reverse lookups of IPv4 addresses are done
by providing an IPv4-mapped IPv6 address to getnameinfo. If
/etc/nsswitch.conf is configured to search "dns" then this
fails if glibc2.2.4 or newer is installed. RedHat 8.0 uses
their own glibc2.2.93 and this is why the problem isn't observed
on RedHat. On reflection the right thing would have been to
provide the IPv4 address to getnameinfo rather than assuming
that getnameinfo can handle an IPv4-mapped IPv6 address.
Note that the issue isn't specific to the getCanonicalHostName
method. Any reverse lookups via InetAddress.getByName will
also run into this issue. This means that most applications
using J2SE 1.4/1.4.1 on SuSE 8.0 will run into this issue.
In the case of SuSE 8.0 the issue can be worked around by changing
the hosts entry in /etc/nsswitch.conf to use dns6 instead of dns.
Alternatively J2SE can be configured be IPv4-only by running it
with java.net.preferIPv4Stack property set to "true". Yet another
workaround is to use the DNS name service provider for InetAddress
by configuring the sun.net.spi.nameservice.provider.1 system property
If this issue isn't addressed in 1.4.2 then we should try to get
it documented as a post-installation task for SuSE 8.0.
Submitted On 12-NOV-2002
hostname --fqdn on the system in question returns the
correct FQDN. An nslookup query of the IP returns the FQDN
for the name as well.
The nsswitch hosts search path is as follows:
hosts: files [notfound=continue] nis [notfound=continue] dns
We tried all combinations possible in the nsswitch search path
(files first, nis first, dns first) and they all had the same result.
We have discovered a workaround since this bug was filed. It
seems that SuSE supports IPv6. Even though we're not using
IPv6, the following modification to nsswitch seems to fix the
hosts: files [notfound=continue] nis [notfound=continue] dns6
I still believe there is an issue with getCanonicalHostname,
however, as both nslookup and hostname bring back the
correct resolution under the old configuration, and
getCanonicalHostname does not.
Submitted On 26-NOV-2002
Thanks for the info. By starting my program with
I was able to get the getCanonicalHostName() function to
work properly on a SuSE System without having to change the
(system wide) nsswitch.conf file.
Submitted On 16-APR-2003
Very usefull info.
We work with many customers that have SuSE servers running
java apps and it's very important for network programming
and security issues that DNS resolve be strong and failsafe.
PLEASE NOTE: JDK6 is formerly known as Project Mustang