jruby/jruby-rack

org.jruby.rack.RackInitializationException: can't convert nil into String

MartinKoerner opened this issue · 8 comments

I use JRuby 1.7.18 with Rails 3.2.22 and Trinidad 1.4.4 on Mac OS X.
My application runs just fine with jruby-rack 1.1.10 - 1.1.14. But starting with 1.1.16 I get the following exception. My colleague on Linux has no problems with 1.1.18 and the same setup.
Were there any configuration changes introduced?

org.jruby.rack.RackInitializationException: can't convert nil into String
    from org/jruby/ext/pathname/RubyPathname.java:206:in `initialize'
    from file:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/jruby-rack-1.1.16/lib/jruby-rack-1.1.16.jar!/jruby/rack/rails/railtie.rb:16:in `Railtie'
    from org/jruby/RubyProc.java:290:in `call'
    from org/jruby/RubyProc.java:271:in `call'
    from /usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/activesupport-3.2.22/lib/active_support/lazy_load_hooks.rb:34:in `execute_hook'
    from /usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/activesupport-3.2.22/lib/active_support/lazy_load_hooks.rb:43:in `run_load_hooks'
    from org/jruby/RubyArray.java:1613:in `each'
    from /usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/activesupport-3.2.22/lib/active_support/lazy_load_hooks.rb:42:in `run_load_hooks'
    from /usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/railties-3.2.22/lib/rails/application.rb:67:in `inherited'
    from /Users/martin/RubymineProjects/project/config/application.rb:17:in `Project'
    from /Users/martin/RubymineProjects/project/config/application.rb:16:in `(root)'
    from org/jruby/RubyKernel.java:1071:in `require'
    from /Users/martin/RubymineProjects/project/config/environment.rb:1:in `(root)'
    from org/jruby/RubyKernel.java:1071:in `require'
    from /Users/martin/RubymineProjects/project/config/environment.rb:3:in `(root)'
    from file:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/jruby-rack-1.1.16/lib/jruby-rack-1.1.16.jar!/jruby/rack/rails/environment3.rb:1:in `(root)'
    from file:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/jruby-rack-1.1.16/lib/jruby-rack-1.1.16.jar!/jruby/rack/rails/environment3.rb:25:in `load_environment'

    at org.jruby.rack.RackInitializationException.wrap(RackInitializationException.java:29)
    at org.jruby.rack.RackApplicationFactoryDecorator.init(RackApplicationFactoryDecorator.java:104)
    at org.jruby.rack.RackServletContextListener.contextInitialized(RackServletContextListener.java:50)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
kares commented

please try using jruby 1.7.22 if it still happens, thanks

Just tried it with jruby 1.7.22, the same exception is thrown with jruby-rack 1.1.16 and 1.1.18

kares commented

thanks, in that case it seems that JRuby::Rack.public_path is somehow nil for you ... you can work-around by setting it to your public directory manually JRuby::Rack.public_path = ... before the Railtie runs. than to resolve this, it would be useful if you could patch the railtie to print the following e.g.

    config.before_configuration do |app|

      puts "JRuby::Rack.context = #{JRuby::Rack.context.inspect}"
      puts "JRuby::Rack.app_path = #{JRuby::Rack.app_path.inspect}"
      puts "JRuby::Rack.context.getRealPath('/') = #{JRuby::Rack.context.getRealPath('/').inspect}"
      puts "JRuby::Rack.public_path = #{JRuby::Rack.public_path.inspect}"

      # ... the real code :
      paths, public = app.config.paths, Pathname.new(JRuby::Rack.public_path)
      if paths.respond_to?(:'[]') && paths.respond_to?(:keys)
      # ...
    end

and report back with your TC version as well (and whether you tried a server upgrade), thanks.

Trinidad uses Tomcat 7.0.37 under the hood. Updating it to 7.0.57 changes nothing. Also updating Trinidad to 1.4.6 doesn't help.

If I patch JRuby::Rack.public_path, the output looks the same in 1.1.18 like the unpatched 1.1.16.

Starting Servlet Engine: Apache Tomcat/7.0.37
jruby 1.7.18 (1.9.3p551) 2014-12-22 625381c on Java HotSpot(TM) 64-Bit Server VM 1.8.0_20-b26 [darwin-x86_64]
using a shared (threadsafe!) runtime
JRuby::Rack.public_path = "/Users/martin/RubymineProjects/project/public"
JRuby::Rack.app_path = "/Users/martin/RubymineProjects/project"
JRuby::Rack.context.getRealPath('/') = "/Users/martin/RubymineProjects/project/"
JRuby::Rack.context = #<Java::OrgJrubyRackServlet::DefaultServletRackContext:0x203938eb>
JRuby::Rack.context.getAttributeNames = #<Java::JavaUtil::Collections:::0xde5981f>
JRuby::Rack.context.getMajorVersion = 3
JRuby::Rack.context.getMinorVersion = 0
JRuby::Rack.context.getRealContext = #<Java::OrgApacheCatalinaCore::ApplicationContextFacade:0x5710ae4b>
JRuby::Rack.context.getServerInfo = "Apache Tomcat/7.0.37"
JRuby::Rack.context.getServletContextName = nil
JRuby::Rack.context.getAttribute('javax.servlet.context.tempdir') = /Users/martin/RubymineProjects/project/tmp
JRuby::Rack.context.getAttribute('org.apache.catalina.resources') = org.apache.naming.resources.ProxyDirContext@5da72bf7
JRuby::Rack.context.getAttribute('org.apache.tomcat.util.scan.MergedWebXml') = <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0"
         metadata-complete="true">
  <session-config>
    <cookie-config>
    </cookie-config>
  </session-config>
</web-app>
JRuby::Rack.context.getAttribute('org.apache.tomcat.InstanceManager') = org.apache.catalina.core.DefaultInstanceManager@acaf060
JRuby::Rack.context.getAttribute('rack.factory') = org.jruby.rack.SharedRackApplicationFactory@30a501a4
JRuby::Rack.context.getAttribute('org.apache.catalina.jsp_classpath') = /Users/martin/RubymineProjects/project/lib/java/classes:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/jruby-rack-1.1.18/lib/jruby-rack-1.1.18.jar:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/trinidad_jars-1.2.2/trinidad-libs/tomcat-core.jar:/usr/local/var/rbenv/versions/jruby-1.7.18/lib/ruby/gems/shared/gems/trinidad_jars-1.2.2/trinidad-libs/trinidad-rb.jar:/Users/martin/RubymineProjects/project/:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/System/Library/Java/Extensions/MRJToolkit.jar
JRuby::Rack.context.getAttribute('rack.context') = org.jruby.rack.servlet.DefaultServletRackContext@203938eb
JRuby::Rack.context.getAttribute('org.apache.tomcat.JarScanner') = org.apache.tomcat.util.scan.StandardJarScanner@6bd47e11

Interestingly, if I use Trinidads option to specify the config.ru file (which normally is only used for non-rails applications), I get the output

JRuby::Rack.public_path = nil

but the application starts (without any css or images of course)

kares commented

thanks, but now I'm confused - you did not get Trinidad to fail while printing the above output, right?
... should have noted that its a little tricky to replace the existing before_configuration

without reproducing I do not see clearly what the cause is, there has been changes in the layout, these .rb parts might be affecting your case ... for now the main suspect although there's other related changes.

Sorry, I added the outputs to Rails' before_configuration, not JRuby::Rack. Now I spammed the jar file with puts statements and finally got to the reason: FileSystemLayout detects "public" as default public dir, but also finds, that that directory is not present. 😔
I found, that it is empty in our case and therefore not included in git.
In development mode, all is fine, since assets are rendered dynamically and in production they are compiled into public during deployment.

I tend to say, that jruby-rack doesn't has to take care about this case, but maybe you can add a more convenient error message.

kares commented

I see thanks - that is about what I ~ thought could explain this ... less weird if it was "only" OSX-specific.

sure can probably warn on missing dir esp. with Rails ... with a simple app a missing public directory is not an issue. I do not have a "real-world" complex app to look at, could you confirm that booting the app in production with webrick with work just fine?

Yes, if I just run "rails server", webrick comes up and the application works fine.