Java Driver
  1. Java Driver
  2. JAVA-249

Java Driver cannot connect to 'localhost' when mongod is listening only on 127.0.0.1 (or "localhost")

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major - P3 Major - P3
    • Resolution: Fixed
    • Affects Version/s: 2.3, 2.4
    • Fix Version/s: 2.8.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      Reproducible on Mac
    • Backward Breaking:
      No
    • Operating System:
      OS X
    • # Replies:
      12
    • Last comment by Customer:
      false

      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
      at com.mongodb.DBPort.findOne(DBPort.java:153)
      at com.mongodb.DBPort.runCommand(DBPort.java:159)
      at com.mongodb.DBTCPConnector.testMaster(DBTCPConnector.java:371)
      at com.mongodb.Mongo.<init>(Mongo.java:167)
      at com.mongodb.Mongo.<init>(Mongo.java:151)
      at com.mongodb.Mongo.<init>(Mongo.java:119)

      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.

        Issue Links

          Activity

          Hide
          Jeff Yemin
          added a comment - - edited

          Using localhost works fine (on a Mac at least) if I comment out the first 3 lines of ServerAddress._getAddress

          
                  if ( host.toLowerCase().equals("localhost") ){
                      return new InetAddress[] { InetAddress.getLocalHost()};
                  }
                  
                  return InetAddress.getAllByName( host );
          

          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.

          Show
          Jeff Yemin
          added a comment - - edited Using localhost works fine (on a Mac at least) if I comment out the first 3 lines of ServerAddress._getAddress if ( host.toLowerCase().equals("localhost") ){ return new InetAddress[] { InetAddress.getLocalHost()}; } return InetAddress.getAllByName( host ); 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.
          Hide
          Raman Gupta
          added a comment -

          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.

          Show
          Raman Gupta
          added a comment - 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 .
          Hide
          Jeff Yemin
          added a comment -

          I'm going to fix this by always using the getByName method in InetAddress.

          Show
          Jeff Yemin
          added a comment - I'm going to fix this by always using the getByName method in InetAddress.
          Hide
          auto
          added a comment -

          Author:

          {u'login': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

          Message: JAVA-249: Removed calls to InetAddress.getLocalHost and InetAddress.getAllByName, using InetAddress.getByName instead
          Simplified code. Fixed Javadoc. Removed unused methods.
          Made it thread-safe by making _address volatile
          Branch: master
          https://github.com/mongodb/mongo-java-driver/commit/3b12c2ae2c208c9e78f75128154e7ead52f00aa1

          Show
          auto
          added a comment - Author: {u'login': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'} Message: JAVA-249 : Removed calls to InetAddress.getLocalHost and InetAddress.getAllByName, using InetAddress.getByName instead Simplified code. Fixed Javadoc. Removed unused methods. Made it thread-safe by making _address volatile Branch: master https://github.com/mongodb/mongo-java-driver/commit/3b12c2ae2c208c9e78f75128154e7ead52f00aa1
          Hide
          Jeff Yemin
          added a comment -

          Closing for 2.8.0 release.

          Show
          Jeff Yemin
          added a comment - Closing for 2.8.0 release.

            People

            • Votes:
              2 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since reply:
                1 year, 44 weeks, 1 day ago
                Date of 1st Reply: