JRuby

War packaged with warble runs on JBoss 4.x and Glassfish 3.x fine, but not on JBoss 5.1

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.3.1
  • Fix Version/s: JRuby 1.x+
  • Component/s: Java Integration
  • Labels:
    None
  • Environment:
    OSX 10.5 & 10.6 with JBoss 5.1
  • Number of attachments :
    6

Description

I create a very simple Sinatra test app and bundle it into a war with warble. I may deploy this war on JBoss 4.0.5 and Glassfish Preview 3 and run it without any problems. When I try to do the same on JBoss 5.1 I get an exception when I try to access the app:

===
Application initialization failed: no such file to load – rack from /Users/jsgoecke/Software/AppServers/jboss-5.1.0.GA/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/vendor/rack.rb:1 from /Users/jsgoecke/Software/AppServers/jboss-5.1.0.GA/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/vendor/rack.rb:22:in `require' from /Users/jsgoecke/Software/AppServers/jboss-5.1.0.GA/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/booter.rb:22:in `boot!' from /Users/jsgoecke/Software/AppServers/jboss-5.1.0.GA/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/boot/rack.rb:9 from /Users/jsgoecke/Software/AppServers/jboss-5.1.0.GA/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-rack-0.9.5.jar/jruby/rack/boot/rack.rb:1:in `load' from
===

I did find that Tomcat 6 set some additional security settings that did not allow wars to access files by default. In this case it can not appear to find rack, even thought it is there and works on the other containers. I will attach the JBoss log and test war as well.

  1. catalina.2009-09-17.log
    17/Sep/09 5:09 AM
    10 kB
    zhao lei
  2. jboss.log
    02/Sep/09 2:02 AM
    23 kB
    Jason Goecke
  3. jruby-3935.patch
    01/Oct/09 12:05 AM
    1 kB
    Jan Topiński
  4. jruby-rack-3935.patch
    01/Oct/09 12:05 AM
    1 kB
    Jan Topiński

Issue Links

Activity

Hide
Nick Sieger added a comment -

Can you try including Rack in your list of gems in your Warbler config? See also the comments on this bug: http://kenai.com/jira/browse/JRUBY_RACK-8

Show
Nick Sieger added a comment - Can you try including Rack in your list of gems in your Warbler config? See also the comments on this bug: http://kenai.com/jira/browse/JRUBY_RACK-8
Hide
Jason Goecke added a comment -

I gave this a try with adding this to the config/warble.rb file:

config.gems += ["sinatra", "rack"]

Also, I did not add that this is with Warble v0.9.14 and Rack 1.0.0.

Show
Jason Goecke added a comment - I gave this a try with adding this to the config/warble.rb file: config.gems += ["sinatra", "rack"] Also, I did not add that this is with Warble v0.9.14 and Rack 1.0.0.
Hide
Jason Goecke added a comment -

Realized I did not make it clear, adding the Rack gem explicitly provided the same results on JBoss 5.1.

Show
Jason Goecke added a comment - Realized I did not make it clear, adding the Rack gem explicitly provided the same results on JBoss 5.1.
Hide
Charles Oliver Nutter added a comment -

So it sounds like a security setting may impact whether an app can inspect or load from the filesystem where the WAR file has been deployed, yes? I assume we're supposed to use classloader resources for this or something?

Did you read about the Tomcat 6 security settings somewhere?

Show
Charles Oliver Nutter added a comment - So it sounds like a security setting may impact whether an app can inspect or load from the filesystem where the WAR file has been deployed, yes? I assume we're supposed to use classloader resources for this or something? Did you read about the Tomcat 6 security settings somewhere?
Hide
Jason Goecke added a comment -

And your description appears to be what is going on, that on this version of JBoss the gems may no longer be read from the filesystem. This does appear to be related:

===
It seems that the default security policies for the tomcat6 package for
Ubuntu don't allow newly deployed applications to read their own files!

I edited /etc/tomcat6/policy.d/50local.policy to allow all permissions
on the deployment directory, and everything started working. The entry I
added was:

grant codeBase "file:${catalina.base}/webapps/-" {
permission java.security.AllPermission;
};
===

Source: http://www.ruby-forum.com/topic/160184

Show
Jason Goecke added a comment - And your description appears to be what is going on, that on this version of JBoss the gems may no longer be read from the filesystem. This does appear to be related: === It seems that the default security policies for the tomcat6 package for Ubuntu don't allow newly deployed applications to read their own files! I edited /etc/tomcat6/policy.d/50local.policy to allow all permissions on the deployment directory, and everything started working. The entry I added was: grant codeBase "file:${catalina.base}/webapps/-" { permission java.security.AllPermission; }; === Source: http://www.ruby-forum.com/topic/160184
Hide
Martin Körner added a comment -

I have the same problem with JBoss 5.1.
Although had it with Tomcat 6, but solved it there (see below)

I don't think, it's a security problem. In Tomcat, you have to activate the SecurityManager manually and in most cases, it's deactivated.
If I it, I get an "IO Error" - like the guy in the ruby forum.
But here it is an "no such file to load".

I had the problem with Tomcat too, as described here: http://kenai.com/projects/jruby-rack/lists/issues/archive/2009-09/message/4
For Tomcat it works, to add "cd $CATALINA_HOME" in the start script, so that the load directory for "rack" and "rubygems" is set correct.
But in JBoss I have no idea, were to set the path, because Tomcat is just a library there...

Show
Martin Körner added a comment - I have the same problem with JBoss 5.1. Although had it with Tomcat 6, but solved it there (see below) I don't think, it's a security problem. In Tomcat, you have to activate the SecurityManager manually and in most cases, it's deactivated. If I it, I get an "IO Error" - like the guy in the ruby forum. But here it is an "no such file to load". I had the problem with Tomcat too, as described here: http://kenai.com/projects/jruby-rack/lists/issues/archive/2009-09/message/4 For Tomcat it works, to add "cd $CATALINA_HOME" in the start script, so that the load directory for "rack" and "rubygems" is set correct. But in JBoss I have no idea, were to set the path, because Tomcat is just a library there...
Hide
zhao lei added a comment - - edited

Tomcat6, virtual server. The $catalina_home is not allow to access. And working path is at "/home/easyactmema5syy7ayclt/wwwroot/", which is not under $catalina_home.
First, I think maybe the promblem is on classLoader.
Maybe current classLoader is in "/home/easyactmema5syy7ayclt/wwwroot/WEB-INF/lib/jruby-rack-0.9.5.jar!", not in "jruby-stdlib-1.3.1.jar". So rack can't load rubegems packed in jruby-stdlib by current classLoader. Though the $LOAD_PATH is setted with "/WEB-INF/lib/jruby-stdlib-1.3.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8", but rack can't load rubygems across different classLoaders. rubygems can't be load, and rack can't work normally.

But I zipped all 3 jar in one jar file, and rubygems is also can't be loaded. Alos get "no such file to load – rack".

Thank god, finally I hacked this! I unzip all 3 jars(core, rack, std) to classes dir, and the server is alright!

Show
zhao lei added a comment - - edited Tomcat6, virtual server. The $catalina_home is not allow to access. And working path is at "/home/easyactmema5syy7ayclt/wwwroot/", which is not under $catalina_home. First, I think maybe the promblem is on classLoader. Maybe current classLoader is in "/home/easyactmema5syy7ayclt/wwwroot/WEB-INF/lib/jruby-rack-0.9.5.jar!", not in "jruby-stdlib-1.3.1.jar". So rack can't load rubegems packed in jruby-stdlib by current classLoader. Though the $LOAD_PATH is setted with "/WEB-INF/lib/jruby-stdlib-1.3.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8", but rack can't load rubygems across different classLoaders. rubygems can't be load, and rack can't work normally. But I zipped all 3 jar in one jar file, and rubygems is also can't be loaded. Alos get "no such file to load – rack". Thank god, finally I hacked this! I unzip all 3 jars(core, rack, std) to classes dir, and the server is alright!
Hide
Piotr Szrajber added a comment - - edited

@zhao lei

> Thank god, finally I hacked this! I unzip all 3 jars(core, rack, std) to classes dir, and the server is alright!

Could you please write something more about that solution? How your .war tree looks now?

I have similar problem with my rails application on JBoss and would like to try your approach.

If it could help anybody, I deal with that problem in such way:

$ find "/JBOSS_PATH/server/my/tmp" -name "*myapp.war" |xargs rm -rf
$ rm -rf "/JBOSS_PATH//server/my/work/jboss.web/localhost/myapp"

and then restart JBoss. After that app usually works, but unfortunately until next restart without above steps...

Show
Piotr Szrajber added a comment - - edited @zhao lei > Thank god, finally I hacked this! I unzip all 3 jars(core, rack, std) to classes dir, and the server is alright! Could you please write something more about that solution? How your .war tree looks now? I have similar problem with my rails application on JBoss and would like to try your approach. If it could help anybody, I deal with that problem in such way: $ find "/JBOSS_PATH/server/my/tmp" -name "*myapp.war" |xargs rm -rf $ rm -rf "/JBOSS_PATH//server/my/work/jboss.web/localhost/myapp" and then restart JBoss. After that app usually works, but unfortunately until next restart without above steps...
Hide
Jan Topiński added a comment - - edited

From what I have tested value of RubyInstanceConfig.jrubyHome is wrongly computed on JBoss. When I manually (in the debuger) changed this value to "/META-INF/jruby.home" your app have greeted me with "Dancing on JBOSS". But I'm not sure how to fix that. The code right now is as follows:
jrubyHome = getClass().getResource("/META-INF/jruby.home")
.toURI().getSchemeSpecificPart();
And than there is:
jrubyHome = verifyHome(jrubyHome);
Both seem wrong for JBoss but may be right in other cases.
If I would guess what to do than:
1) if getClass().getResource("/META-INF/jruby.home") returns not null set jrubyHome = "META-INF/jruby.home"
2) There is nothing to verify if one found "/META-INF/jruby.home" on classpath so just don't call verifyHome at all.

I will implement it for a try on http://github.com/simcha/jruby.
Will be grateful for any advise.

Show
Jan Topiński added a comment - - edited From what I have tested value of RubyInstanceConfig.jrubyHome is wrongly computed on JBoss. When I manually (in the debuger) changed this value to "/META-INF/jruby.home" your app have greeted me with "Dancing on JBOSS". But I'm not sure how to fix that. The code right now is as follows: jrubyHome = getClass().getResource("/META-INF/jruby.home") .toURI().getSchemeSpecificPart(); And than there is: jrubyHome = verifyHome(jrubyHome); Both seem wrong for JBoss but may be right in other cases. If I would guess what to do than: 1) if getClass().getResource("/META-INF/jruby.home") returns not null set jrubyHome = "META-INF/jruby.home" 2) There is nothing to verify if one found "/META-INF/jruby.home" on classpath so just don't call verifyHome at all. I will implement it for a try on http://github.com/simcha/jruby. Will be grateful for any advise.
Hide
Jan Topiński added a comment -

Just realized that in jruby-rack in DefaultRackApplicationFactory newRuntime method that code is nearly the same:

try { // try to set jruby home to jar file path String binjruby = RubyInstanceConfig.class.getResource( "/META-INF/jruby.home/bin/jruby").toURI().getSchemeSpecificPart(); config.setJRubyHome(binjruby.substring(0, binjruby.length() - 10)); } catch (Exception e) { }

so one should patch there as well I think.

Show
Jan Topiński added a comment - Just realized that in jruby-rack in DefaultRackApplicationFactory newRuntime method that code is nearly the same: try { // try to set jruby home to jar file path String binjruby = RubyInstanceConfig.class.getResource( "/META-INF/jruby.home/bin/jruby").toURI().getSchemeSpecificPart(); config.setJRubyHome(binjruby.substring(0, binjruby.length() - 10)); } catch (Exception e) { } so one should patch there as well I think.
Hide
Jan Topiński added a comment - - edited

This is a version of your app with patches applied to jruby and jruby-rack I tested it on jboss 4.2.3 and 5.1 and it's ok.

Show
Jan Topiński added a comment - - edited This is a version of your app with patches applied to jruby and jruby-rack I tested it on jboss 4.2.3 and 5.1 and it's ok.
Hide
Jan Topiński added a comment -

And this are patches one for jruby branch jruby-1_3 and other for master at jruby-rack.

Show
Jan Topiński added a comment - And this are patches one for jruby branch jruby-1_3 and other for master at jruby-rack.
Hide
Jan Topiński added a comment -

Did more testing it's not working properly with gems and generally not working properly with jruby ChannelDescription hack for jars. I will try to fix it correctly.

Show
Jan Topiński added a comment - Did more testing it's not working properly with gems and generally not working properly with jruby ChannelDescription hack for jars. I will try to fix it correctly.
Hide
Charles Oliver Nutter added a comment -

Jan: Thanks for digging into this, we'll wait to hear more from you.

Show
Charles Oliver Nutter added a comment - Jan: Thanks for digging into this, we'll wait to hear more from you.
Hide
Luke Chadwick added a comment -

This issue also happens with the following environment:

  • Windows XP SP3
  • JBoss 5.1.0 GA
  • warbler (0.9.14)
  • jruby-jars (1.4.0)
  • sinatra (0.9.4)

Since its been a couple of months, I'll assume Jan isn't still working on it, and I'll
have a play around on the weekend. No promises of fixing the issue, but I'll let you know
if I make any breakthroughs.

Show
Luke Chadwick added a comment - This issue also happens with the following environment:
  • Windows XP SP3
  • JBoss 5.1.0 GA
  • warbler (0.9.14)
  • jruby-jars (1.4.0)
  • sinatra (0.9.4)
Since its been a couple of months, I'll assume Jan isn't still working on it, and I'll have a play around on the weekend. No promises of fixing the issue, but I'll let you know if I make any breakthroughs.
Hide
Vladimir Sizikov added a comment -

This seems to be dragging for quite a while. And if the issue in JRuby proper, I'll be able to fix it, but first I really need to reproduce the problem!

Can somebody write a step-by-step instructions on how to reproduce the problem? Preferably, with minimal setup.

I just tried the attached WARs on Tomcat on Windows, and they worked just fine with no problems at all.

Show
Vladimir Sizikov added a comment - This seems to be dragging for quite a while. And if the issue in JRuby proper, I'll be able to fix it, but first I really need to reproduce the problem! Can somebody write a step-by-step instructions on how to reproduce the problem? Preferably, with minimal setup. I just tried the attached WARs on Tomcat on Windows, and they worked just fine with no problems at all.
Hide
Vladimir Sizikov added a comment -

OK, installed JBoss, and the problem is easily reproducible there, yeah.

Doesn't look like JRuby's issue though, more like jruby-rack one. Since jruby-rack sets the jruby's home in this case, and the current code in jruby-rack can't handle JBoss case.

JBoss uses custom classloaders and custom vfszip/zfsjar scheme, like this:

vfszip:/D:/re/jboss/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-stdlib-1.3.1.war/META-INF/jruby.home/bin/jruby

So, the URL above points to the WAR file, but the actual content is extracted into some temp directory. Naturally, setting JRuby's home to

D:/re/jboss/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-stdlib-1.3.1.war/META-INF/jruby.home

doesn't work.

And I'm not sure how this should be really handled in jruby-rack.... One thing for sure, relying on getSchemeSpecificPart of URL, returned by (arbitrary) classloader is not a 100% safe/workable solution.

Show
Vladimir Sizikov added a comment - OK, installed JBoss, and the problem is easily reproducible there, yeah. Doesn't look like JRuby's issue though, more like jruby-rack one. Since jruby-rack sets the jruby's home in this case, and the current code in jruby-rack can't handle JBoss case. JBoss uses custom classloaders and custom vfszip/zfsjar scheme, like this: vfszip:/D:/re/jboss/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-stdlib-1.3.1.war/META-INF/jruby.home/bin/jruby So, the URL above points to the WAR file, but the actual content is extracted into some temp directory. Naturally, setting JRuby's home to D:/re/jboss/server/default/deploy/sinatra-test.war/WEB-INF/lib/jruby-stdlib-1.3.1.war/META-INF/jruby.home doesn't work. And I'm not sure how this should be really handled in jruby-rack.... One thing for sure, relying on getSchemeSpecificPart of URL, returned by (arbitrary) classloader is not a 100% safe/workable solution.
Hide
Vladimir Sizikov added a comment -

OK, so I've just committed a new code, in rev. 3e44eb3, that introduces a new scheme to load resources from the classpath. Namely, "classpath:/foo/bar".

It is useful is such cases when we can't use jar:file URL to access the JAR file.

For example, JRuby's home can be set to:

classpath:/META-INF/jruby.home

and that should be pretty functional.

But there are severe limitations, like there is no proper globbing, and that makes rubygems non-functional. Rubygems use glob to find spec files, etc, and we can't do such things from the classpath alone.

One possibility is to tweak rubygems so that it would look into some pre-built index instead of live search with globs.

At any rate, I thought it would be useful for this bug as well. at least, there is a possibility now to experiment with classpath:/META-INF/jruby.home as JRuby's home and see how it goes, etc.

Show
Vladimir Sizikov added a comment - OK, so I've just committed a new code, in rev. 3e44eb3, that introduces a new scheme to load resources from the classpath. Namely, "classpath:/foo/bar". It is useful is such cases when we can't use jar:file URL to access the JAR file. For example, JRuby's home can be set to:
classpath:/META-INF/jruby.home
and that should be pretty functional. But there are severe limitations, like there is no proper globbing, and that makes rubygems non-functional. Rubygems use glob to find spec files, etc, and we can't do such things from the classpath alone. One possibility is to tweak rubygems so that it would look into some pre-built index instead of live search with globs. At any rate, I thought it would be useful for this bug as well. at least, there is a possibility now to experiment with classpath:/META-INF/jruby.home as JRuby's home and see how it goes, etc.
Hide
Steven Hansen added a comment - - edited

There is simple work around for this problem on JBoss 5.x:

Assuming you have the archive myapp.war

1) Extract the contents of myapp.war into a dir called myapp.war
2) Extract the contents of myapp.war/WEB-INF/lib/jruby-core-1.4.0.jar into the dir myapp.war/WEB-INF/lib/jruby-core-1.4.0.jar
3) Extract the contents of myapp.war/WEB-INF/lib/jruby-rack-0.9.5.jar into the dir myapp.war/WEB-INF/lib/jruby-core-0.9.5.jar
4) Extract the contents of myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar into the dir myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar

The app will deploy with out the annoying error:

16:27:50,703 ERROR [STDERR] Warning: JRuby home "/opt/application_servers/jboss-5.1.0.GA/server/default/deploy/myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar/META-INF/jruby.home" does not exist, using /tmp

Until this problem is fixed, just write a rake task, or extend warbler, to perform these steps as part of the build.

Show
Steven Hansen added a comment - - edited There is simple work around for this problem on JBoss 5.x: Assuming you have the archive myapp.war 1) Extract the contents of myapp.war into a dir called myapp.war 2) Extract the contents of myapp.war/WEB-INF/lib/jruby-core-1.4.0.jar into the dir myapp.war/WEB-INF/lib/jruby-core-1.4.0.jar 3) Extract the contents of myapp.war/WEB-INF/lib/jruby-rack-0.9.5.jar into the dir myapp.war/WEB-INF/lib/jruby-core-0.9.5.jar 4) Extract the contents of myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar into the dir myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar The app will deploy with out the annoying error:
16:27:50,703 ERROR [STDERR] Warning: JRuby home "/opt/application_servers/jboss-5.1.0.GA/server/default/deploy/myapp.war/WEB-INF/lib/jruby-stdlib-1.4.0.jar/META-INF/jruby.home" does not exist, using /tmp
Until this problem is fixed, just write a rake task, or extend warbler, to perform these steps as part of the build.
Hide
Nick Sieger added a comment -

I think this will be fixed in the upcoming JRuby-Rack 0.9.7 release, or alternately, possibly JRuby 1.5. This problem seems to be related to http://kenai.com/jira/browse/JRUBY_RACK-8.

Marking as resolved, if you can wait and try these new releases and report back, that would be great.

Show
Nick Sieger added a comment - I think this will be fixed in the upcoming JRuby-Rack 0.9.7 release, or alternately, possibly JRuby 1.5. This problem seems to be related to http://kenai.com/jira/browse/JRUBY_RACK-8. Marking as resolved, if you can wait and try these new releases and report back, that would be great.

People

Vote (3)
Watch (4)

Dates

  • Created:
    Updated:
    Resolved: