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:^[email protected]
^G:^[email protected]^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