Search code examples
javanashornscriptengine

Setting "Callable" on a Java object from within Nashorn script


I have a class instance that has a Callable field on it. I set this instance on a Bindings object. I need to set the Callable field from within Nashorn, to be called in Java. How would I set this field from within a Nashorn script?

The script is called like this:

//in java
class Options {
    Callable<Boolean> handler;
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Bindings bindings = engine.createBindings();
Options options = new Options();
bindings.put("options", options);
engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
engine.eval(script);
Invocable executor = (Invocable) engine;
executor.invokeFunction("init");

And in the script, I need to set the handler field on the global Options object:

//in nashorn
function init() {
    //How would I set a Callable on this field, from within nashorn?
    options.handler = ?
}

I have seen the (suggested duplicate) question How to use Nashorn engine to call Java Objects, but that question is about calling a Java method from a Nashorn script, whereas this question is about setting a callable inside a Nashorn script, which can then be called from Java (basically the opposite).


Solution

  • Based on the 'Extending classes' section in this nashorn tutorial. Tested, worked for me:

       var Callable = Java.type('java.util.concurrent.Callable');
       var CallableImpl = Java.extend(Callable, {
         call: function() {
           print('test');
         }
       });
       
       options.handler = new CallableImpl();