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