Mixing Nashorn with Rhino
Paul Bakker
pgbakker at gmail.com
Fri May 15 09:42:04 UTC 2015
Hi,
Bare with me for a sec while I explain my setup: I'm working with a Java
application which using Rhino to provide scripting capabilities.
I now need to provide from within this Rhino scripting environment a new
level of scripting access, which should have a limited scope, as in it
shouldn't have access to all stuff the Rhino scripting layer already has
access to.
While I could probably achieve this from the Rhino scripting layer by
instantiating a new Rhino scripting engine/scope/context/...., I came up
with the idea to use Nashorn instead. This way I achieve a few things:
1: the Nashorn scripting environment is completely encapsulated from
whatever is already accessible from the Rhino scripting environment
2: better performance of the JavaScript executed in the new
Nashorn-based scripting layer
3: up to date JavaScript support (now, but mostly in the future (ES2015
and beyond))
4: Gain experience myself in using Nashorn
Now, I've gotten so far as to instantiate a Nashorn script engine with
only plain JavaScript API exposed from Rhino:
var scl = java.lang.ClassLoader.getSystemClassLoader()
var factory =
java.lang.Class.forName('jdk.nashorn.api.scripting.NashornScriptEngineFactory',
true, scl).getConstructor().newInstance()
var nashornEngine = factory.getScriptEngine(['-strict',
'--no-java', '--no-syntax-extensions'])
Next I try to expose some object with methods in Nashorn and this is
where I am running into an issue: While I can expose the object in
Nashorn without problems, when a script in Nashorn tries to execute one
of the methods of the object, it fails with the following error:
=> testNashorn()
org.mozilla.javascript.WrappedException: Wrapped
javax.script.ScriptException: TypeError:
org.mozilla.javascript.InterpretedFunction at 6ada780a is not a function in
<eval> at line number 1 (C:\workspaces\test\master\engine\engine.js#9)
The code of my attempt is below. Note that this code is executed from
within Rhino:
function testNashorn() {
var logger = {
debug: function(){
java.lang.System.out.println('testing')
}
}
nashornEngine.getContext().setAttribute('log1', logger,
Packages.javax.script.ScriptContext.ENGINE_SCOPE)
nashornEngine.eval("log1.debug('hello')")
nashornEngine.put('log2', logger)
nashornEngine.eval("log2.debug('hello')")
}
My understanding is that Nashorn isn't able to execute a function that
is defined in Rhino (in this case the debug method of the logger object).
Now my basic question is: can this be done, some way or the other? I
know this is not your typical setup, but it is the one I have to work
with and I really like to implement the required functionality using
Nashorn for the stated reasons.
Hope someone can shed some light on this.
TIA,
Paul
More information about the nashorn-dev
mailing list