[JAVA-249] Java Driver cannot connect to 'localhost' when mongod is listening only on 127.0.0.1 (or "localhost") Created: 05/Jan/11 Updated: 18/Jun/12 Resolved: 14/May/12 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | None |
| Affects Version/s: | 2.3, 2.4 |
| Fix Version/s: | 2.8.0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Brendan W. McAdams | Assignee: | Jeffrey Yemin |
| Resolution: | Done | Votes: | 2 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Reproducible on Mac |
||
| Issue Links: |
|
||||||||||||||||||||
| Backwards Compatibility: | Fully Compatible | ||||||||||||||||||||
| Description |
|
Issue reported by user but reproducible by me. When working with the 2.4 Java driver on Mac OS X (10.6.x) , where mongod listens on bind_ip 127.0.0.1 (also tried with 'localhost'), an empty Mongo constructor [Mongo()] connects. However, connecting to a hostname of "localhost" fails with: com.mongodb.MongoInternalException: DBPort.findOne failed Adding an explicit port number makes no difference.' User reports they see same behavior if they specify a hostname of "127.0.0.1" although on my machine with a homebrew sourced 1.6.3 and 1.6.5 it functions with "127.0.0.1". If I remove the bind_ip declaration it works fine. User reports behavior did not occur with the 2.1 Java driver — I've confirmed this. Uncertain if it happens on other platforms yet. |
| Comments |
| Comment by Jeffrey Yemin [ 18/Jun/12 ] | ||||||
|
Closing for 2.8.0 release. | ||||||
| Comment by auto [ 14/May/12 ] | ||||||
|
Author: {u'login': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}Message: | ||||||
| Comment by Jeffrey Yemin [ 11/May/12 ] | ||||||
|
I'm going to fix this by always using the getByName method in InetAddress. | ||||||
| Comment by Raman Gupta [ 13/Mar/12 ] | ||||||
|
Yes, InetAddress.getLocalHost() does not mean "ip address associated with localhost". Rather, it means the "ip address associated with the local i.e. current host's name". Typically, this means that the IP address will be resolved to the external interface and not 127.0.0.1, which is not what a user would expect. As noted by Jeff in the previous comment, there should not be an override for "localhost" to InetAddress.getLocalHost(). Rather InetAddress.getAllByName( host ); where host = "localhost" leaves the resolution of the name "localhost" to the OS, as the user would expect. I just ran into this issue on a new CentOS EC2 instance, so this is not confined to Mac's, and funnily enough just submitted a pull request to GitHub with the same exact change Jeff proposed a couple of days ago: https://github.com/mongodb/mongo-java-driver/pull/65. | ||||||
| Comment by Jeffrey Yemin [ 10/Mar/12 ] | ||||||
|
Using localhost works fine (on a Mac at least) if I comment out the first 3 lines of ServerAddress._getAddress
InetAddress.getAllByName("localhost") will resolve to the loopback address, whereas InetAddress.getLocalHost() calls java.net.InetAddressImpl#getLocalHostName which does not always return "localhost", in which case it will try to look up the local host name in DNS, which will typically fail on a dev machine. For instance, on my dev machine it returns "jmpb.home" Another thing we may want to do is to try all the InetAddress instances returned by InetAddress.getAllByName, instead of just the first one, until we find one that works. | ||||||
| Comment by Brendan W. McAdams [ 14/Jan/11 ] | ||||||
|
Unfortunately, this is classified as either a Java-level or OS-level bug, and is not occurring within the Mongo driver. The resolution error occurs in the layer between Java and the Operating System as it resolves the hostname and can't be addressed in Mongo's Java code. | ||||||
| Comment by Martin Grotzke [ 13/Jan/11 ] | ||||||
|
We also encounter this on a gentoo, with java driver 2.4. Changing localhost to 127.0.0.1 works, however, it should be possible to be able to connect with "localhost" to 127.0.0.1. | ||||||
| Comment by Brendan W. McAdams [ 05/Jan/11 ] | ||||||
|
It turns out this is a quirk in the resolver on Mac and some Debians (per EH); localhost != 127.0.0.1 in these cases. We should report a better error message to clarify that we couldn't resolve the host. | ||||||
| Comment by Brendan W. McAdams [ 05/Jan/11 ] | ||||||
|
Confirmed as a Mac only bug, and it occurs in the java.net.InetSocketAddress constructor. Looking to see if there are any crucial differences in the Mac JDK impl of ISA versus stock Sun. | ||||||
| Comment by Brendan W. McAdams [ 05/Jan/11 ] | ||||||
|
The breakage is happening in line 43 of DBPort.java, the getSocketAddress() call on ServerAddress. I am confirming it doesn't break on other platforms and if it is mac only it is likely a bug on Mac's Java implementation. The getSocketAddress() call is returning a different address than input — when it is called against a ServerAddress for 'localhost' it instead of returning localhost/127.0.0.1:27017 like it should, returns <system-public-hostname>/<system-public-ip>:<port> If the MongoD is not listening on the public ip the connection fails. Here is the debug dump from a Scala console: scala> MongoConnection("127.0.0.1") scala> MongoConnection("localhost") | ||||||
| Comment by Brendan W. McAdams [ 05/Jan/11 ] | ||||||
|
Reproduced issue on 2.3 java driver as well as 2.4; doesn't occur with 2.2 or earlier. | ||||||
| Comment by Brendan W. McAdams [ 05/Jan/11 ] | ||||||
|
Mongod log shows in the case of the exception thrown connect attempts no connection is made to mongod, so this isn't the command failing but the actual connection. |