Resource resolution in a packed JRuby web app war deployed on Tomcat

Hi friendly JRuby folk,

I’m encountering some issues with resolving paths to ruby files when a
JRuby
web application is deployed to Tomcat as a packed war file. When the
war is
deployed unpacked, path resolution to ruby scripts and gems works just
fine.

The war file is built using warbler, and gems are packaged under the
/WEB-INF/gems directory. When loading the application Tomcat gives the
following error:

Application initialization failed: no such file to load – sinatra
from
file:/home/bhaidri/applications/apache-tomcat-6.0.29/work/Catalina/localhost/voldemort/WEB-INF/lib/jruby-stdlib-1.5.2.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require’

I noticed that when I do a ‘puts File.expand_path(FILE)’ in the
unpacked war, I’m correctly resolved to the WEB-INF directory of the
web application. When that same line of code is run in the packed
war, it outputs the root of the tomcat installation.

Am I missing something or is this some wierd class loader/path foo going
on
inside Tomcat/JRuby?

Thanks,
Baq

On Wed, Nov 17, 2010 at 5:52 PM, Baq H. [email protected] wrote:

from

file:/home/bhaidri/applications/apache-tomcat-6.0.29/work/Catalina/localhost/voldemort/WEB-INF/lib/jruby-stdlib-1.5.2.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in

`require’

I noticed that when I do a ‘puts File.expand_path(FILE)’ in the unpacked
war, I’m correctly resolved to the WEB-INF directory of the web application.
When that same line of code is run in the packed war, it outputs the root
of the tomcat installation.

Am I missing something or is this some wierd class loader/path foo going on
inside Tomcat/JRuby?

Might be, hard to say. We’ve been dogged by custom webapp classloaders
and war files that don’t get unpacked before. Might I suggest putting
the following in web.xml (or config/warble.rb):

jruby.rack.debug.load true

config.webxml.jruby.rack.debug.load = true

This will dump out $LOAD_PATH and some additional info when you hit the
error.

/Nick

Hey Nick et al,

So yes I did turn on debug logging in Rack and also did a whole bunch
more
debugging today, dumping the load path and the class path, etc. Here’s
what
I found:

  1. Dumping the ruby script into the WEB-INF/classes directory inside a
    packed war allows JRuby to find the script since it’s now available on
    the
    regular Tomcat classpath.
  2. After fixing #1, our Sinatra app starts returning 404’s (when it
    worked
    perfectly fine unpacked).
  3. This is because Sinatra uses references to the location of the
    current
    script when building an application using the ‘classic DSL’ style. This
    won’t work when the script is inside a war file.
  4. Changing the application to be an extension of Sinatra::Base does
    work
    but I haven’t yet tested whether path resolution to things like external
    templates works; will test that later.

In a parallel effort, we’re trying to get our production-configured
Tomcat
to unpack the war upon deploying and dealing with some issues around
that
not working. If we could get that working than we might just dump the
packed-war effort and have a little bit of operational overhead for
deploying our JRuby apps, which ordinarily we wanted to avoid.

–Baq