Understanding ScriptContext

I’m trying to call JRuby from Java.

I have two JRuby ScriptEngines; I want them to share the same context.

I declare the method “getFoo” on e1 with the shared context; I then
try and evaluate the method “getFoo” on e2 with the same shared
context. However, the method getFoo does not seem to see this
declaration. I thought that when I evaluated the declaration with a
given context, that would be stored in the context. Is this wrong?
Is there something wrong with my example (written in scala)? Any help
would be greatly appreciated.

import javax.script._
import org.jruby._

val manager = new ScriptEngineManager
val e1 = manager.getEngineByName(“jruby”)
val e2 = manager.getEngineByName(“jruby”)

val context = new SimpleScriptContext

e1.eval(“def foo; x = 1; x; end”, context)
// Generates res4: java.lang.Object = null

e2.eval(“getFoo”, context)
// Passing in the same context from where I defined the method, yet it
throws:

javax.script.ScriptException: org.jruby.exceptions.RaiseException:
undefined local variable or method `getFoo’ for main:Object
at
com.sun.script.jruby.JRubyScriptEngine.evalNode(JRubyScriptEngine.java:456)
at
com.sun.script.jruby.JRubyScriptEngine.eval(JRubyScriptEngine.java:180)

Hello,

On Wed, Jun 8, 2011 at 5:25 PM, Matt H. [email protected]
wrote:

would be greatly appreciated.
e1.eval(“def foo; x = 1; x; end”, context)
// Generates res4: java.lang.Object = null

e2.eval(“getFoo”, context)
// Passing in the same context from where I defined the method, yet it throws:

javax.script.ScriptException: org.jruby.exceptions.RaiseException:
undefined local variable or method `getFoo’ for main:Object
at com.sun.script.jruby.JRubyScriptEngine.evalNode(JRubyScriptEngine.java:456)
at com.sun.script.jruby.JRubyScriptEngine.eval(JRubyScriptEngine.java:180)

Yes, it should be. Ruby runtime knows the method “foo” but don’t know
“getFoo” method. So, you need to change “getFoo” to “foo” .
One more. You don’t need to write “x;” because Ruby returns an
evaluation result of “x = 1” .
As far as I tested, the code below worked and printed 1.

import javax.script._

val manager = new ScriptEngineManager
val e1 = manager.getEngineByName(“jruby”)
val e2 = manager.getEngineByName(“jruby”)

val context = new SimpleScriptContext

e1.eval(“def foo; x = 1; end”, context)
println(e2.eval(“foo”, context))

Hope this helps,
-Yoko

Ah, yes good catch on the method name; I have had that correct in the
past. Your example still failed, but I am running against JRuby
1.1.2. When I tested the same code against the latest – 1.6.2 –
everything worked as expected.

Thanks!

On Thu, Jun 9, 2011 at 7:27 AM, Matt H. [email protected]
wrote:

Ah, yes good catch on the method name; I have had that correct in the
past. Your example still failed, but I am running against JRuby
1.1.2. When I tested the same code against the latest – 1.6.2 –
everything worked as expected.

That’s good.

JRuby 1.1.2 is a way old version. JSR223 support wasn’t included.
Probably, you used Sun’s reference implementation whose Ruby runtime
isn’t a singleton. So, the code didn’t work. JRuby 1.6.2 has JSR223
impl whose runtime is a singleton in a default setting. No matter how
many JSR223 engines are instantiated, only one runtime is there.
Please go to wiki, RedBridge · jruby/jruby Wiki · GitHub , for
detail.

-Yoko