Wednesday, December 19, 2007

JRuby 1.0.3, Rails 2.0.2, Rubygems 0.9.5

So here's the deal... The easiest way to install Rails is through Rubygems, which automatically creates the "rails command" that invokes the rails application skeleton generator, in your ruby bin directory, and sticks rails in the rubygems load path so that you can require 'rubygems' and then require 'activerecord' etc.

Problems start to pop up when you try installing Rails 2.0 (the current, production-ready Rails) in JRuby. As I mentioned earlier, the new gems were created with Rubygems 0.9.5 rather than Rubygems 0.9.4 which ships in the JRuby binary package. In C-Ruby, you can easily upgrade Rubygems by running gem update --system. That runs gem's update_command.rb, which pulls down the latest rubygems-update-XXX.gem file, unpacks it, and then runs this little ditty:


Dir.chdir update_dir do
say "Installing RubyGems #{version_string}"
setup_cmd = "#{Gem.ruby} setup.rb #{args.join ' '}"

# Make sure old rubygems isn't loaded
if Gem.win_platform? then
system "set RUBYOPT= & #{setup_cmd}"
else
system "RUBYOPT=\"\" #{setup_cmd}"
end
end


Did you catch that? UnSet the environment variable RUBYOPT, and re-run the ruby command in the install directory, running setup.rb. Like I said, it works fine in C-Ruby, but here's how Gem.ruby is defined in Rubygems 0.9.4:


# Return the Ruby command to use to execute the Ruby interpreter.
def ruby
"ruby"
end


And here it is in 0.9.5:

# Return the Ruby command to use to execute the Ruby interpreter.
def ruby
if @ruby.nil? then
@ruby = File.join(Config::CONFIG['bindir'],
Config::CONFIG['ruby_install_name'])
@ruby << Config::CONFIG['EXEEXT']
end

@ruby
end


Which is correct. The old version just says, "the ruby interpreter command is 'ruby', and that's that." Which doesn't do a lick of good if ruby isn't in your path, and more importantly, if the command is jruby and not ruby! So running gem update --system won't do any good in JRuby. We can get around that by pulling down the gem and running setup.rb manually with JRuby:

bin\jruby -S gem install rubygems-update --no-rdoc --no-ri
cd lib\ruby\gems\1.8\gems\rubygems-update-0.9.5
..\..\..\..\..\..\bin\jruby setup.rb --no-rdoc --no-ri
cd ..\..\..\..\..\..


Now, there's one more issue with Rubygems to fix before we can get Rails installed. Fire up this bit of code in bin\jirb:

fname='lib/ruby/site_ruby/1.8/rubygems/version.rb'
lines = File.readlines fname
lines[126]


You should get back: " @ints <=> other.ints\n", and ints is an attr_accessor. Makes sense, but if you just try installing rails at this point, there's an issue where checking against version 0 does not properly initialize the ints array, which is just a major/minor version number split on dots. What we need to check is to_ints, which splits the version number and returns @ints, so try this:

lines[126].gsub! /@ints|(\.)ints/, "\\1to_ints"
File.open(fname,'w'){|f| lines.each{|line| f.write line } }


Now, you can run bin\jruby -S gem install rails --no-rdoc --no-ri and be good to go. Note that Rubygems 0.9.5 has -y (--include-dependencies) as the default option, and will nag you if you specify it.

Cheers!

0 Comments:

Post a Comment

<< Home