Friday, December 21, 2007

JRuby 1.0.3, Rubygems 0.9.5 TypeError

Here's that error again: After updating Rubygems to 0.9.5 (yeah, I know 1.0.0 just came out, but that one does some weird stuff with bin script filenames that I'd rather not deal with right now), trying to install rails gives:

ERROR: While executing gem ... (TypeError)
can't convert nil into Array


Running gem with the -V and --backtrace options makes it seem that the problem comes up from checking a default Ruby version requirement. Gem::Requirement.default creates a new Gem::Requirement with version GTE 0, and when it compares that version 0 to the Ruby version 1.8.5, the 0 doesn't properly get turned into an array [0] and gets left as nil, which when compared to an Array causes the above TypeError. Patching Rubygems to make it compare to_ints to to_ints rather than @ints to #ints works around the problem, but doesn't address the real issue: why does the same code work in MRI but not JRuby?

So I fired up jirb and started checking it out, and found that Gem::Version#normalize and to_ints weren't being called when comparing to the version requirement from the gemspec. Comparing to the Gem::Requirement.default worked fine.

According to the response I got from Eric on the Rubygems patch I submitted, @ints gets set from Version#initialize, #yaml_initialize, and #marshal_load. So why isn't it getting set for the default in this case? All of those constructor methods call self.version=, and #version= calls normalize to turn the version string into an array. Initialize seemed to work, but a gemspec uses yaml, and I found that yaml_initialize isn't being called!


class Foo
def initialize
@foo=1
end
def yaml_initialize tag, val
@foo=5
end
end
foo=Foo.new
YAML.load YAML.dump(foo) # #


Doh! yaml_initialize is definitely NOT being called. So I submitted JRUBY-1786, and hopefully Ola Bini or someone else will know how to fix it in the java code. In the meantime, my rubygems/version.rb workaround still does the trick.

0 Comments:

Post a Comment

<< Home