Bugs: Browse | Submit New | Admin

[#27865] Glassfish gem fails to correctly work with rails 3 beta

Date:
2010-02-21 11:09
Priority:
3
Submitted By:
Mark Titorenko (mjtitorenko)
Assigned To:
Vivek Pandey (vivekp)
Category:
gem
State:
Open
Target Release:
 
Summary:
Glassfish gem fails to correctly work with rails 3 beta

Detailed description
Firstly, let me state that I am not sure whether these are all glassfish gem issues or whether some pertain to upstream
glassfish issues.  I'm not yet certain where one ends and the other begins! :-)

Having said that, here is what I had to do in order to get the glassfish gem working with a rails 3 beta installation
as a Rails application rather than a Rack application and working with concurrent requests:

1. Allow glassfish to detect that the application is a Rails application by adding the following tag to boot.rb:

# RAILS_ROOT #

(Probable upstream glassfish issue.)

2. Add glassfish gem to #{RAILS_ROOT}/Gemfile so that the jruby/rails_path.rb file is required. eg.

gem "glassfish", "1.0.3.dev"

3. Modify the jruby/rails_path.rb to work within Rails 3:

diff -r glassfish-1.0.3.dev-universal-java.orig/lib/jruby/rails_path.rb
glassfish-1.0.3.dev-universal-java/lib/jruby/rails_path.rb
1,6c1,22                                                                                         
< module Rails                                                                                   
<   class Configuration                                                                          
<     def threadsafe?                                                                            
<       if(Rails::Configuration.instance_methods.include?'threadsafe!')                          
<         if(Rails::Configuration.instance_methods.include?'preload_frameworks')                 
<           preload_frameworks && cache_classes && !dependency_loading &&
action_controller.allow_concurrency
---                                                                                                          
> if Module === Rails::Configuration                                                                         
>   # Rails 3                                                                                                
>   module Rails                                                                                             
>     class Application                                                                                      
>       class Configuration                                                                                  
>         def threadsafe?                                                                                    
>           allow_concurrency                                                                                
>         end                                                                                                
>       end                                                                                                  
>     end                                                                                                    
>   end                                                                                                      
> else                                                                                                       
>   # Rails 2                                                                                                
>   module Rails                                                                                             
>     class Configuration                                                                                    
>       def threadsafe?                                                                                      
>         if(Rails::Configuration.instance_methods.include?'threadsafe!')                                    
>           if(Rails::Configuration.instance_methods.include?'preload_frameworks')                           
>             preload_frameworks && cache_classes && !dependency_loading &&
action_controller.allow_concurrency
>           else                                                                                             
>             cache_classes && !dependency_loading && action_controller.allow_concurrency       
>           end                                                                                              
8c24                                                                                                         
<           cache_classes && !dependency_loading && action_controller.allow_concurrency         
---                                                                                                          
>           false                                                                                            
10,11d25                                                                                                     
<       else                                                                                                 
<         false 

4. Modify the rack/adapter/rails.rb file to operate with Rails 3:

diff -r glassfish-1.0.3.dev-universal-java.orig/lib/rack/adapter/rails.rb
glassfish-1.0.3.dev-universal-java/lib/rack/adapter/rails.rb
77,81c77,83                                                                                                  
<         @rails_app = if rack_based?                                                                        
<           ActionController::Dispatcher.new                                                                 
<         else                                                                                               
<           CgiApp.new                                                                                       
<         end                                                                                                
---                                                                                                          
>         @rails_app = if rails3?                                                                            
>                        ::Rails.application                                                                 
>                      elsif rack_based?                                                                     
>                        ActionController::Dispatcher.new                                                    
>                      else                                                                                  
>                        CgiApp.new                                                                          
>                      end                                                                                   
86a89,92                                                                                                     
>       def rails3?                                                                                          
>         ::Rails.application.respond_to?(:call) rescue false                                                
>       end                                                                                                  
>                                                                                                            
99,101c105,108                                                                                               
<         require 'dispatcher'                                                                               
<                                                                                                            
<         setup_logger                                                                                       
---                                                                                                          
>         if !rails3?                                                                                        
>           require 'dispatcher'                                                                             
>         end                                                                                                
>           setup_logger                                                                                     
248,249c255,258                                                                                              
<             class << ::RAILS_DEFAULT_LOGGER # Make these accessible to wire in the log device              
<               public :instance_variable_get, :instance_variable_set                                        
---                                                                                                          
>             if !rails3?                                                                                    
>               class << ::RAILS_DEFAULT_LOGGER # Make these accessible to wire in the log device            
>                 public :instance_variable_get, :instance_variable_set                                      
>               end

Even though the Rails application did initially function as a Rack application, concurrent requests were not possible
with config.threadsafe! enabled in production mode and, to me, this is really a fundamental reason to use JRuby and
Glassfish to run a rails app!

Even with these modifications it is still not possible for the glassfish gem to host a rails application in daemonized
mode - it seems to spin up using JRubyRuntime rather than using the RackApplicationPoolFactory.  I'm uncertain as to
why but perhaps, again, this is an upstream Glassfish issue as I seem to get a similar effect when using the full app
server.

Compare the following:

Daemonized:

INFO: Running testapp in production environment.
19-Feb-2010 13:26:48 org.glassfish.scripting.jruby.RackApplicationChooser detectRails
INFO: Rails application detected.
19-Feb-2010 13:26:48 org.glassfish.scripting.jruby.JRubyApplication <init>
INFO: Loading application alice at /
19-Feb-2010 13:26:48 com.sun.grizzly.jruby.RackGrizzlyAdapter <init>
INFO: JRuby version is: 1.4.0
19-Feb-2010 13:26:49 com.sun.grizzly.jruby.rack.JRubyRuntime <init>
INFO: New instance of JRuby runtime created in 88 milliseconds

(Requests always return the "please wait while your application is being started" page.)

Non-daemonized:

INFO: Running testapp in production environment.
19-Feb-2010 13:28:39 org.glassfish.scripting.jruby.RackApplicationChooser detectRails
INFO: Rails application detected.
19-Feb-2010 13:28:39 org.glassfish.scripting.jruby.JRubyApplication <init>
INFO: Loading application alice at /
19-Feb-2010 13:28:39 com.sun.grizzly.jruby.RackGrizzlyAdapter <init>
INFO: JRuby version is: 1.4.0
19-Feb-2010 13:28:45 com.sun.grizzly.jruby.rack.RackApplicationPoolFactory newApplication
INFO: New instance of rails created in 6,020 milliseconds

(Requests function as expected.)

Apologies if I've ended up filing bugs that are mainly related to upstream Glassfish issues - however, you are more
likely to have a good understanding of which issues are where than I! :-)

Add A Comment: Notepad

Please login


Followup

Message
Date: 2010-03-02 20:53
Sender: Arun Gupta

Tried creating a Rails 3 app as described at: 

http://blog.nicksieger.com/articles/2010/02/24/jruby-and-rails-3-
sitting-in-a-tree

Running the application gave:

Mar 2, 2010 12:48:34 PM org.glassfish.scripting.jruby.JRubyApplication
<init>
INFO: Loading application newapp at /
Mar 2, 2010 12:48:34 PM com.sun.grizzly.jruby.RackGrizzlyAdapter
<init>
INFO: JRuby version is: 1.5.0.dev
Mar 2, 2010 12:48:44 PM com.sun.grizzly.jruby.RackGrizzlyAdapter
service
SEVERE: Failed to create JRuby instance.
java.util.concurrent.ExecutionException:
java.lang.ArrayIndexOutOfBoundsException: -1
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTa
sk.java:222)
        at java.util.concurrent.FutureTask.get(FutureTask.java:83
)
        at com.sun.grizzly.jruby.RackGrizzlyAdapter.service(RackG
rizzlyAdapter.java:289)
        at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(Griz
zlyAdapter.java:166)
        at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2
Dispatcher.java:100)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.se
rvice(ContainerMapper.java:245)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(Proce
ssorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(Processor
Task.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTa
sk.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(Def
aultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFi
lter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultPr
otocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultPr
otocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpPro
tocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(Protoc
olChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(Selection
KeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(
AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(Abs
tractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:637)
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
        at org.jruby.runtime.ThreadContext.getCurrentScope(Thread
Context.java:194)
        at org.jruby.Ruby.evalScriptlet(Ruby.java:285)
        at com.sun.grizzly.jruby.rack.RackupApplication.createApp
licationObject(RackupApplication.ja
va:55)
        at com.sun.grizzly.jruby.rack.RackupApplication.<init&
gt;(RackupApplication.java:51)
        at com.sun.grizzly.jruby.rack.RackApplicationPoolFactory.
newApplication(RackApplicationPoolF
actory.java:102)
        at com.sun.grizzly.jruby.rack.RackApplicationPoolFactory.
getRackApplocationPool(RackApplicat
ionPoolFactory.java:66)
        at com.sun.grizzly.jruby.RackGrizzlyAdapter.startJRubyRun
time(RackGrizzlyAdapter.java:124)
        at com.sun.grizzly.jruby.RackGrizzlyAdapter.access$000(Ra
ckGrizzlyAdapter.java:69)
        at com.sun.grizzly.jruby.RackGrizzlyAdapter$1.call(RackGr
izzlyAdapter.java:109)
        at com.sun.grizzly.jruby.RackGrizzlyAdapter$1.call(RackGr
izzlyAdapter.java:106)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTa
sk.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:13
8)
        at java.util.concurrent.Executors$RunnableAdapter.call(Ex
ecutors.java:441)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTa
sk.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:13
8)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask
(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Thr
eadPoolExecutor.java:908)
        ... 1 more
Mar 2, 2010 12:48:45 PM com.sun.grizzly.jruby.RackGrizzlyAdapter
service

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item