Mixing Jruby and Java in a Java Threadpool

Hi guys, I’m new to the list.

I did quite a lot of Googling, but didn’t find any specific references
to this topic.

I have a number of simple Java servers which can invoke a series of Java
classes on each other. Each server maintains its own threadpool, and a
given series of classes is executed in parallel using the threadpool’s
invokeAll() method.

I’m extending the server to be able to invoke JRuby scripts as well. So
I need to submit to the threadpool a list containing a potential mix of
Java classes and JRuby scripts.

My question regards the ScriptingContainer.

Can each server maintain just one instance of a ScriptingContainer and
run the various scripts inside? BTW, the scripts themselves never access
any shared JRuby resources, and any access to shared Java resources are
always synchronized in Java.

Are there any performance limitations to this approach (it seems to me
much cleaner just keeping one persistent container instance than
spawning new ones for each JRuby thread). Are there any practical
limitations as to how many scripts can be loaded and executed in a given

If I can use just one container, does JRuby check if the same script is
being loaded more than once into a given container? - the server could
call multiple instances of the same script. In other words, do I have
to maintain a list of loaded scripts and only load a script if it’s not
already in the container, or does runScriptlet() do this for me?

To prevent the server’s memory footprint growing over time, Java classes
are automatically unloaded if they are not called during a certain
period. I was wondering if I could do something similar with a scripting
container, ie selectively unload scripts. Of course I could always
clear() the container, but this would also remove any “hot” scripts as

Thanks in advance for any answers, and apologies if my questions belie a
lack of understanding as to how ScriptingContainers are actually
implemented. I looked quite hard for some implementation descriptions,
but came up empty - of course, I could always look at the source, but
whenever I take that route I generally end up more confused :slight_smile:

David S.

Hi David,

You have two options for sharing a runtime amongst threads:
LocalContextScope.SINGLETON or SINGLETHREAD. The former uses the same
runtime for the whole JVM every time you create a ScriptingContainer,
the latter relies on you sharing the same ScriptingContainer instance
with the thread pool.

As far as sharing/reloading scripts, it depends on whether you use
#load or #require. #require will load the script once and all the
classes created will be reused, otherwise the scripts will be re-run
each time.

Hope that helps,


Nick, thanks very much for your reply.

Before writing my original email I took a look at the javadoc for
LocalContextScope. What was not clear to me is the definition of a

For example, consider this script:

class MyClass(a,b)
def initialize(a,b)
@a = a
@b = b
def multiply
a * b

def execute(a,b)
my_object = MyClass.new(a,b)
sleep 1

If in Java I created a container with any of the four
LocalContextScopes, and then called container.callMethod(receiver,
“execute”, args) in multiple concurrent threads would each instance of
execute be thread safe? In other words, do objects in the outermost
scope and instance variables count as “variables”? (I hope this is

Clearly the risk here is that a given my_object is created, but then
either it or its instance variables get clobbered while execute is

As regards your second point, yes I understand how loading would work
within a container, but it’s unclear to me how it would do so from the
For example, if I ran the following code:

receiverA = container.runScriptlet(PathType.ABSOLUTE, “test.rb”);
receiverB = container.runScriptlet(PathType.ABSOLUTE, “test.rb”);

Would test.rb be loaded twice? If not, would receiverA.equals(receiverB)
be true?

Thanks again for your help and congratulations on “Using JRuby” - I was
so engrossed I read it from cover to cover in one session!!



Sorry, that should have been @a * @b in the multiply method.