I am using daemon kit to start a background ruby process that listens for Amazon SQS messages. Once a message is received then it starts an child process with Open3.popen3 that needs to run in JRuby.
The background process needs to run in MRI since daemon kit uses Process.daemon to daemonize the process. But so far I haven't been able to force the child process to run in JRuby.
I am using rbenv to manage ruby versions so at first I thought this would work:
Open3.popen3({"RUBY_VERSION" => "jruby-1.7.8"}, "rp5 run /path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
# read stderr and stdout for status and error information ....
end
But in the child process output I was getting the error: "rbenv: jruby: command not found"
Then I tracked how the rbenv runs it's executables so that I could bypass rbenv and run directly the rp5 executable in JRuby.
I first found the rp5 executable in the folder: ~/.rbenv/versions/jruby-1.7.8/bin/rp5
#!/Users/fede/.rbenv/versions/jruby-1.7.8/bin/jruby
#
# This file was generated by RubyGems.
#
# The application 'ruby-processing' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/
version = $1
ARGV.shift
end
end
gem 'ruby-processing', version
load Gem.bin_path('ruby-processing', 'rp5', version)
Then I executed the Gem.bin_path method to find which rp5 executable it was calling. Which is inside the gem: ~/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 And then I tried running the child process by calling this rp5 executable directly:
Open3.popen3("~/.rbenv/versions/jruby-1.7.8/lib/ruby/gems/shared/gems/ruby-processing-2.3.1/bin/rp5 run path/to/sketch.rb") do |stdin, stdout, stderr, wait_thr|
# read stderr and stdout for status and error information ....
end
But I was still getting the same "jruby command not found" error.
And then I inspected that executable:
#!/usr/bin/env ruby
file = __FILE__
if test(?l, file)
require "pathname"
file = Pathname.new(file).realpath
end
require File.expand_path(File.dirname(file) + "/../lib/ruby-processing")
Processing::Runner.execute
So does the shebang at the top means that this executable is using the default ruby version?
Is it even possible to launch a child process in an entirely different ruby version?
Thanks.
have you tried "forcing" it to run in the interpreter by simply running
ruby -S
e.g. :so first find out where the MRI ruby executable is located and than use that instead of
/usr/bin/ruby
that should simply do what you're looking for ...