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