I’m seeing an exception creep up that does not happen when config.threadsafe! is disabled on my JRuby on Rails application. This tends to creep up when I restart tomcat6, but it can happen after the application startup as well. I’m seeing a lot of errors such as the following:
uninitialized constant Foo::Check
org/jruby/RubyModule.java:2590:in `const_missing'
My application continues to work fine and serves requests without issues. I’m just curious what could be the cause of these newfound exceptions? Is this some generic, known issue? Do I need to provide more code for the different areas of the app where this exact error is creeping up to further diagnose?
The core issue is that require is not a threadsafe activity in ruby. One aspect of that is that class definition does not happen atomically.
Consider the following, in foo.rb
Thread 1 hits
Foo::BARsomewhere in your app, and starts loading foo.rb. It gets as far asclass Foo, creating the Foo class, but no further. Thread 1 then gets preempted and thread 2 also hitsFoo::BAR. Foo is already defined so foo.rb is not loaded again, however BAR is not yet defined (it will be when thread 1 completes it’s require) and so you get a const missing error. In the same way, aFooobject created at this point wouldn’t have abarmethod for a brief fraction of a second.Obviously, the bigger a class is, the greater this window is (to make it easier to see, you can stick a call to sleep partway through the class definition)
To work around this, rails loads all of your application code at application startup, but if you have code in non standard locations it won’t be getting this treatment. You can control what gets loaded like this via the
config.eager_load_pathssetting.