I have a small library, say widget_utils.rb, that lives in the lib/ directory of the app. (I’ve set the config to autoload source files from lib/)
The utils include the ‘spira’ gem which does ORM mapping based on RDF.rb. In the widget_utils.rb file are class objects based on my RDF repository, and they refer to a type called Spira::Types::Native.
I have a static method in WidgetUtils that returns a hash based on RDF data for use in rendering, WidgetUtils.options_for_select.
If I launch the console, I can call WidgetUtils.options_for_select and get back my hash perfectly.
But if I run the server, and try to render /widget/1234 or /widget/1234/edit to show one widget, I get the error Unrecognized type: Spira::Types::Native
At the bottom of my stack trace is widget_controller.rb, and at some point the haml file is doing a “load” of “lib/widget_utils.rb”, and crashing with the Unrecognized type at the point where it’s referenced in the util source file.
From the console if I do “load ‘lib/widget_utils.rb'” I get no error, the type is recognized successfully.
I’m stumped, and too new to rails to successfully come up with a strategy to solve this problem outside of trial and error.
As it turns out, this problem is specific to the Spira library I’m working with, and JRuby when serving pages.
Spira keeps its collected known RDF types in a “settings” hash that it makes thread local. In most ordinary circumstances on MRI Ruby/Rails this isn’t an issue, since the requests are usually handled in the same thread as the Spira initialization.
Similar problems will occur under JRuby if you attempt to make data global through, for instance, class variables. Some other mechanism needs to be found to make global reference data available to all service threads. (Mutable shared data is not even something to consider unless you like headaches.)
There is a workaround for Spira that will keep its settings available. In my utility class I added this monkey patch to take the settings out of Thread.local: