JRuby and YAML

May 20, 2009

I ran into a little problem when I converted our apache rewrite rule automated tests to use jruby instead of ruby. These tests use a little ruby driver which makes http requests to a local apache instance. The script reads a few yaml files which contain the url to test, and the expected result after Apache has done its mod_rewrite magic.

Using the MRI ruby meant having to install ruby on all developer machines, build boxes, and keep those ruby installations in sync. So I changed the ant script to pull jruby-complete.jar (1.2.0) from ivy, and run the tests in that. My tests started failing with ParserException messages about “found org.jvyamlb.tokens.KeyToken”. These were all yaml files that MRI ruby handles without complaint.

After much trial-and-error, slicing the yaml files up into smaller chunks to isolate the rules, I found the problem. Commas. In normal ruby, you can have them your values as long as they are not followed by a space. In jruby, you have to quote them. Arguably, JRuby is doing the right thing – I haven’t delved into the yaml spec enough to find out.

Here’s an example irb session with JRuby:

irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> YAML.load("{url: http://someurl/path,with,commas, http_code: 200}")
ArgumentError: syntax error:ParserException while scanning a flow node we had this expected the node content, but found org.jvyamlb.tokens.KeyToken
        from (irb):3

Do the same with quoted strings:

irb(main):004:0> YAML.load("{url: \"http://someurl/path,with,commas\", http_code: 200}")
=> {"url"=>"http://someurl/path,with,commas", "http_code"=>200}

Similarly, unquoted strings containing question marks (“?”) were truncated.

irb(main):005:0> YAML.load("{url: http://someurl/path?with=query, http_code: 200}")
=> {"with=query"=>nil, "url"=>"http://someurl/path", "http_code"=>200}

Again, quoting the value solved the problem. Hopefully this helps anyone else that has YAML parsing problems in JRuby.

Here’s a little snippet from one of our ant files for running Cucumber as an Ant task, under JRuby. Read the rest of this entry »