Say you wanted to store some information across different calls to your JRuby/Rails application on the server side. You could use a database, or memcached. However, what if you just want to do something very simple like a basic cache, and you don’t have a database for your application? Memcached seems like overkill, and would complicate your deployment considerably. So, what about just using statics?
Well, you can’t do it in Ruby, as the Rails integration servlet spawns multiple instances of the JRuby interpreter.
Ruby code in a page view:
<h1>Ruby global number</h1>
<% $i ||= 0 %>
<% $i += 1 %>
<%= $i %>
<h1>Ruby obj id</h1>
<% $o ||= Object.new %>
<%= $o.object_id %>
Results between multiple refreshes of the page:
Ruby global number
1
Ruby obj id
244
Ruby global number
1
Ruby obj id
256
Ruby global number
2
Ruby obj id
244
Ruby global number
2
Ruby obj id
256
Our requests seem to be switching between two instances of the Ruby interpreter.
However, we *can* do it in Java. My clever, Java-literate colleagues explained that Java application servers and servlet containers use a single instance of the JVM, but have a class loader for each application. The class loader stores class information and static values. This means that within one application, the static values will be maintained between requests, but a different application on the same server will have its own set of unrelated static values (similar to AppDomains in .NET).
If we add a call to a static method in Java that increments an integer and returns it, our view looks like this:
<h1>Ruby global number</h1>
<% $i ||= 0 %>
<% $i += 1 %>
<%= $i %>
<h1>Ruby obj id</h1>
<% $o ||= Object.new %>
<%= $o.object_id %>
<h1>Java incrementing static integer</h1>
<%= TestClass.incrementAndReturnNumber() %>
Our results now look a lot more useful. The Java static integer is getting incremented each call to the view:
Ruby global number
1
Ruby obj id
244
Java number
1
Ruby global number
1
Ruby obj id
256
Java number
2
Ruby global number
2
Ruby obj id
244
Java number
3
Ruby global number
2
Ruby obj id
256
Java number
4
From this little experiment, Java statics seem like a possible way to go for storing temporary data on the server side (eg, a cache implemented as a singleton) for JRuby / Rails. Another option may be to use the ServletContext from the JRuby Rails integration servlet – probably an area worth investigating.