JRuby Rack doesn’t work with Sinatra
After much poking and prodding it looks like Sinatra won’t work on top of JRuby Rack. It’s an unintended consequence of how everything was implemented, and it looks like some (hopefully minor) changes will have to be made to Sinatra.
Steps to get to where I am:
- Install JRuby 1.1.2
- Get tomcat - I used a 6.0.14 install I had laying around
- Install the JRuby gem “warble”, which will come with jruby-rack
- Create a new directory structure, described below
- Copy jruby-complete.jar, and jruby-rack.jar to the WEB-INF/lib directory
- Create a simple Sinatra hello world app
- Create your web.xml file as described
The directory structure
jruby-sinatra/ jruby-sinatra/WEB-INF jruby-sinatra/WEB-INF/web.xml jruby-sinatra/WEB-INF/hello_world.rb jruby-sinatra/WEB-INF/sinatra # full copy of sinatra goes here jruby-sinatra/WEB-INF/lib jruby-sinatra/WEB-INF/lib/jruby-complete-1.1.1.jar jruby-sinatra/WEB-INF/lib/jruby-rack-0.9.jar
My (non-working) current web.xml file.
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <context-param> <param-name>public.root</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>rackup</param-name> <param-value> $:.unshift '/Users/cschneid/servers/apache-tomcat-6.0.14/webapps/jruby-sinatra/WEB-INF/' $:.unshift '/Users/cschneid/servers/apache-tomcat-6.0.14/webapps/jruby-sinatra/WEB-INF/sinatra/lib' puts "=====================" puts "=====================" puts "=====================" puts "Current file is: #{__FILE__}" puts "Dollar 0 is: #{$0}" puts "List of load paths:" puts $:.map {|a| puts a } puts "=====================" puts "=====================" puts "=====================" puts "Requiring sinatra" require "sinatra" puts "Setting up the sinatra app options" Sinatra::Application.default_options.merge!( :run => false, :env => :production ) puts "About to require test" require 'test' puts "About to run sinatra" run Sinatra.application </param-value> </context-param> <filter> <filter-name>RackFilter</filter-name> <filter-class>org.jruby.rack.RackFilter</filter-class> </filter> <filter-mapping> <filter-name>RackFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.jruby.rack.RackServletContextListener</listener-class> </listener> </web-app>
The problem - the load fails on the Sinatra::Application.default_options.merge line. The first time you access default_options, it generates the hash. Every subsequent time, it just hands back the already created instance. Since this is the first time, it attempts to create the default_options structure. It gets a “root” of the directory tree from $0. And then later combines it with ‘/views’ and ‘/public’. The problem lies in the fact that we have a ruby script embedded inside the web.xml file. It doesn’t have a reasonable $0 to even set, so it doesn’t. If you ask for __FILE__, it just reports back with “<script>”. End result: you get a simple “can’t convert nil into String” exception thrown.
Next Steps - I don’t know, I think we should probably wean Sinatra off of $0 if at all possible. Or at least figure out how to set it to something reasonable so that default_options doesn’t blow up. If anybody has any ideas on how to go about this, let me know, since this doesn’t have an obvious fix that I see. Mainly, I don’t want to break functionality elsewhere (for plain ruby).
June 10th, 2008 at 7:18 am
I think there’s a bunch of stuff we can do in JRuby-Rack to make this go better, including making it so you don’t have to embed the rackup script inside web.xml. Thanks for pointing out the deficiencies, hopefully we can get it working by the next release.
July 25th, 2008 at 12:30 pm
An update on this: I got Sinatra working by artificially setting $0. This should work in the forthcoming 0.9.1.
October 27th, 2008 at 1:04 pm
[…] public links >> jruby JRuby Rack doesn’t work with Sinatra Saved by dyom on Sun 26-10-2008 Update to “Using JDBC Connection Pools with NetBeans 6, JRuby […]