Problem of using jruby and warbler to deploy my ruby on rails app to resin

Hi,

My ruby on rails application is a forum like system which needs people’s
login to make a post.
The login function is based on cookie and the authentication is from
another
web service.
If a user’s login is valid, the web service will make the cookie for my
app. All is OK when
I use C Ruby Mongrel or JRuby Mongrel. But when I use warbler to make a
war
to deploy
it to resin, problem occurs after I login. The log of RoR shows as
following

[FATAL] /!\ FAILSAFE /!\ Mon Jan 12 22:38:23 +0800 2009
Status: 500 Internal Server Error
End of file reached

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/cgi/session/java_servlet_store.rb:24:in
`load’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/cgi/session/java_servlet_store.rb:24:in
`restore’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-complete-1.1.6.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/builtin/java/collections.rb:74:in
`each’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/cgi/session/java_servlet_store.rb:20:in
`restore’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-complete-1.1.6.jar!/cgi/session.rb:304:in
`[]’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/cgi_process.rb:98:in
`session’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/cgi_process.rb:130:in
`stale_session_check!’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/cgi_process.rb:78:in
`session’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/base.rb:1205:in
`assign_shortcuts’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/flash.rb:166:in
`assign_shortcuts_with_flash’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/base.rb:519:in
`process’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/filters.rb:606:in
`process_with_filters’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/session_management.rb:134:in
`process_with_session_management_support’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/base.rb:392:in
`process’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:183:in
`handle_request’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:110:in
`dispatch_unlocked’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:123:in
`dispatch’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:122:in
`dispatch’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:132:in
`dispatch_cgi’

/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:39:in
`dispatch’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/rack/adapter/rails.rb:37:in
`serve_rails’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/rack/adapter/rails.rb:55:in
`call’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/jruby/rack/rails.rb:145:in
`call’

file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/rack/handler/servlet.rb:17:in
`call’
:1

I use :

  • jruby 1.1.6
  • rails 2.2.2
  • warbler 0.9.12

To find the reason, I have already tried a lot. After some days’
searching
and reading, nothing found.
finally I un-packaged the jruby-rack-0.9.3.jar, added some log info into
java_servlet_store.rb, and
re-packaged it, copied it to
/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/,
and restarted the resin.

The log codes I added in java_servlet_store.rb is :

  # Restore session state from the Java session
  def restore
    @session_data = {}
    java_session = @java_request.getSession(false)
    if java_session
      java_session.getAttributeNames.each do |k|
        if k == RAILS_SESSION_KEY
          marshalled_bytes =

java_session.getAttribute(RAILS_SESSION_KEY)
if marshalled_bytes
# data =
Marshal.load(String.from_java_bytes(marshalled_bytes))
marshalled_string = String.from_java_bytes(marshalled_bytes)
puts “”
puts “restore : marshalled_string = #{marshalled_string}” #added for
debug
data = Marshal.load(marshalled_string)
@session_data.update data if Hash === data
end
else
@session_data[k] = java_session.getAttribute(k)
end
end
end
@session_data
end

  # Save session state to the Java session
  def update

puts “”
puts “== update ==========================================”
java_session = @java_request.getSession(true)
hash = @session_data.dup
hash.delete_if do |k,v|
if String === k
case v
when String, Numeric, true, false, nil
puts “hash : k=#{k} v=#{v} **”
java_session.setAttribute k, v
true
else
if v.respond_to?(:java_object)
puts “hash : k=#{k} v=#{v.to_string} **”
java_session.setAttribute k, v
true
else
puts “hash : k=#{k} v=#{v} ***”
false
end
end
end
end
unless hash.empty?
marshalled_string = Marshal.dump(hash)
puts “marshalled_string = *** #{marshalled_string} ***” #added for debug
marshalled_bytes = marshalled_string.to_java_bytes
java_session.setAttribute(RAILS_SESSION_KEY, marshalled_bytes)
test_string = String.from_java_bytes(marshalled_bytes)
puts “string equals!!!” if test_string == marshalled_string
begin
data = Marshal.load(test_string)
puts “hash equals!!!” if data==hash
rescue
puts “Marshal.load exception!!!”
end

end
end

And the log result is :

== update ==========================================
hash : k=flash v= ***
marshalled_string = *** ^D^H{^K"
flashIC:'ActionController::Flash::FlashHash{^@^F:
@used{^@ssn0:^Kmobile0:^Gip0:
email0:^Olast_login0 ***
string equals!!!
hash equals!!!

restore : marshalled_string = ^D^H{^K"
flashIC:'ActionController::Flash::FlashHash{^@^F:
@used{^@ssn0:^Kmobile0:^Gip0:
email0:^Olast_login0

== update ==========================================
hash : k=flash v= ***
marshalled_string = *** ^D^H{^K"
flashIC:'ActionController::Flash::FlashHash{^@^F:
@used{^@ssn0:^Kmobile0:^Gip0:
email0:^Olast_login0 ***
string equals!!!
hash equals!!!

restore : marshalled_string = ^D^H{^K"
flashIC:'ActionController::Flash::FlashHash{^@^F:
@used{^@ssn0:^Kmobile0:^Gip0:
email0:^Olast_login0

== update ==========================================
hash : k=flash v= ***
marshalled_string = *** ^D^H{^K"
flashIC:'ActionController::Flash::FlashHash{^@^F:
@used{^@ssn"^[email protected]:^Kmobile"^@:^Gip"^R:
email"^[email protected]:^Olast_loginu:
Date=^D^Ho:^MRational^G:^Q@denominatori
^G:^O@numeratori^CyJi^@i^C^Y^U# ***
string equals!!!
Marshal.load exception!!!

That is to say, the update function in java_servlet_store.rb use Marshal
to
dump a object as a string, but the string cannot restore to the object
using Marshal.load. Exception is “End of file reached”. (The first two
‘update’ logs are corresponding to anonymous user’s page view)

Does anyone know the problem and how to solve it?

Thanks

Harry
2008-1-14

OK, at last I cannot help downloading the source code of JRuby, and
looked
at this

RubyHash.java :

// FIXME:  Total hack to get flash in Rails 

marshalling/unmarshalling in
session ok…We need
// to totally change marshalling to work with overridden core
classes.
public static void marshalTo(final RubyHash hash, final
MarshalStream
output) throws IOException {
//…
//…
}

That’s it! I think my problem is exactly that described in the ‘FIXME’
of
RubyHash.java code.
So… when will this issue be fixed? Could the author see this mail?

Harry

On Thu, Jan 15, 2009 at 12:25 AM, harry wang [email protected] wrote:

  //......
  //......

}

That’s it! I think my problem is exactly that described in the ‘FIXME’ of
RubyHash.java code.
So… when will this issue be fixed? Could the author see this mail?

Congratulations on finding the source of your bug. Any chance you want
to try digging in and finding it? Or at least writing a small test
case to reproduce your problem? Sounds like it should be a
straightforward test that marshal-roundtrips a special hash, but you
would know better than us because you have the code that breaks it.

If you could post a reproducing test case to JIRA
(http://jira.codehaus.org/browse/JRUBY) it would greatly increase your
chances of seeing it get fixed.

/Nick

another web service.

`restore’
/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/cgi_process.rb:78:in

`handle_request’
/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:132:in

  • warbler 0.9.12

    Restore session state from the Java session

Marshal.load(String.from_java_bytes(marshalled_bytes))
end
if String === k
else
java_session.setAttribute(RAILS_SESSION_KEY, marshalled_bytes)

email0:^Olast_login0 ***
marshalled_string = *** ^D^H{^K"
using Marshal.load. Exception is “End of file reached”. (The first two


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

This bug seems to demonstrate this issue:

http://jira.codehaus.org/browse/JRUBY-3289

Someone else noticed this bug at the same time. They even applied a
non-Rails test case. Is flashhash a common thing to save in a
session? It looks like two people have tried to do this recently.

-Tom

On Thu, Jan 15, 2009 at 8:56 AM, Nick S. [email protected]
wrote:

output) throws IOException {
case to reproduce your problem? Sounds like it should be a

If a user’s login is valid, the web service will make the cookie for my
file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/cgi/session/java_servlet_store.rb:24:in

`session’
/opt/resin-3.0.21/webapps/ROOT/WEB-INF/gems/gems/actionpack-2.2.2/lib/action_controller/filters.rb:606:in

`dispatch_cgi’
file:/opt/resin-3.0.21/webapps/ROOT/WEB-INF/lib/jruby-rack-0.9.3.jar!/jruby/rack/rails.rb:145:in

  def restore

marshalled_string = String.from_java_bytes(marshalled_bytes)
@session_data
case v
puts “hash : k=#{k} v=#{v} ***”
test_string = String.from_java_bytes(marshalled_bytes)
And the log result is :
restore : marshalled_string = ^D^H{^K"
string equals!!!
flashIC:'ActionController::Flash::FlashHash{^@^F:
‘update’ logs are corresponding to anonymous user’s page view)


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Blog: http://www.bloglines.com/blog/ThomasEEnebo
Email: [email protected] , [email protected]


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email