Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mongoid driver does not work in JRuby on Windows or JRuby loads incorrect socket constants on Windows. #5477

Closed
cshupp1 opened this Issue Nov 27, 2018 · 1 comment

Comments

Projects
None yet
3 participants
@cshupp1
Copy link

commented Nov 27, 2018

Consider the following irb session:

irb(main):001:0> JRUBY_VERSION
=> "9.2.4.0"
irb(main):005:0> require 'socket'
=> true
irb(main):009:0> Socket::PF_INET
=> 4
irb(main):016:0> java.lang.System.getProperties['os.name']
=> "Windows 10"

Let us compare it to MRI Ruby:

irb(main):001:0> RUBY_VERSION
=> "2.5.1"
irb(main):002:0> RUBY_PLATFORM
=> "x64-mingw32"
irb(main):003:0> require 'socket'
=> true
irb(main):004:0> Socket::PF_INET
=> 2

Note the socket constants are not consistent. What about JRuby on Linux?

java -jar jruby-complete-9.2.4.0.jar -S jirb
irb(main):001:0> java.lang.System.getProperties['os.name']
=> "Linux"
irb(main):002:0> require 'socket'
=> true
irb(main):003:0> Socket::PF_INET
=> 2

The Mongoid driver versions:

    mongoid (6.4.2)
    mongo (2.6.2)

fail as a result. On a stock rails install (5.2.1) with the mongoid driver installed the following model:

class ToyModel
  include Mongoid::Document
  include Mongoid::Timestamps
  store_in :collection => "toy_model"
  field :toy, :type => String
end

with the following code:

 t = ToyModel.new
 t.toy = "rails server coming up at #{Time.now}"
 t.save!

fails as follows:

MONGODB | EVENT: #<Mongo::Monitoring::Event::TopologyOpening topology=Unknown>
MONGODB | Topology type 'unknown' initializing.
MONGODB | EVENT: #<Mongo::Monitoring::Event::ServerOpening address=127.0.0.1:27017 topology=Unknown>
MONGODB | Server 127.0.0.1:27017 initializing.
MONGODB | undefined method `new' for nil:NilClass
MONGODB | undefined method `new' for nil:NilClass
MONGODB | undefined method `new' for nil:NilClass #<===repeats forever...

The following monkey patch, in an initializer, repairs the problem:

WINDOWS = java.lang.System.getProperties['os.name'] =~ /windows/i
if WINDOWS
  module Mongo
    PF_INET = 2 #Socket::PF_INET = 2 #2 in MRI ruby, 4 in JRuby on windows, 2 on Linux. We need 2.
    class Address
      def socket(socket_timeout, ssl_options = {})
        unless ssl_options.empty?
          Socket::SSL.new(host, port, host_name, socket_timeout, Mongo::PF_INET, ssl_options)#force it to see properly defined constant
        else
          Socket::TCP.new(host, port, socket_timeout, Mongo::PF_INET)#Mongo:: is Socket:: in original code
        end
      end
    end
  end
else
  puts "Linux Yay!"
end

Now the same toy_model code yields:

irb(main):001:0> t = ToyModel.new
=> #<ToyModel _id: 5bfdc5168726e31af7d27464, created_at: nil, updated_at: nil, toy: nil>
irb(main):002:0> t.toy = "rails server coming up at #{Time.now}"
=> "rails server coming up at 2018-11-27 17:28:44 -0500"
irb(main):003:0> t.save!
MONGODB | EVENT: #<Mongo::Monitoring::Event::TopologyOpening topology=Unknown>
MONGODB | Topology type 'unknown' initializing.
MONGODB | EVENT: #<Mongo::Monitoring::Event::ServerOpening address=127.0.0.1:27017 topology=Unknown>
MONGODB | Server 127.0.0.1:27017 initializing.
MONGODB | EVENT: #<Mongo::Monitoring::Event::TopologyChanged prev=Unknown new=Single>
MONGODB | Topology type 'unknown' changed to type 'single'.
MONGODB | EVENT: #<Mongo::Monitoring::Event::ServerDescriptionChanged>
MONGODB | Server description for 127.0.0.1:27017 changed from 'unknown' to 'standalone'.
MONGODB | EVENT: #<Mongo::Monitoring::Event::TopologyChanged prev=Single new=Single>
MONGODB | There was a change in the members of the 'single' topology.
MONGODB | 127.0.0.1:27017 | dif_development.insert | STARTED | {"insert"=>"toy_model", "ordered"=>true, "lsid"=>{"id"=><BSON::Binary:0x2058 type=uuid data=0x063280eed79c45b4...>}, "documents"=>[{"_id"=>BSON::ObjectId('5bfdc5168
726e31af7d27464'), "toy"=>"rails server coming up at 2018-11-27 17:28:44 -0500", "updat...
MONGODB | 127.0.0.1:27017 | dif_development.insert | SUCCEEDED | 0.012s
=> true
irb(main):004:0>

@ahorek

This comment has been minimized.

Copy link
Contributor

commented Nov 28, 2018

a simple hack is to use Socket::AF_INET instead of Socket::PF_INET, anyway fixed in the related PR, thanks for the report

@enebo enebo added this to the JRuby 9.2.5.0 milestone Nov 28, 2018

enebo added a commit that referenced this issue Nov 29, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.