2

I'm using javax.script to embed javascript code to a Java method.

In my project the javascript takes care to send asynchronous http request through a websocket. Once a response is received I need to execute a callback function.

I would like to invoke a method written in Java as a callback.

In the documentation here: http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/ it is explained how to implement java methods in javascript for an interface, but not how to invoke Java methods form javascript.

Thanks

Piero
  • 169
  • 1
  • 2
  • 10

2 Answers2

1

Not sure if this is exactly what you are looking for, but here is a code sample that supplies a java object callback into some javascript code that will then call back on that callback later:

public class JsCallback{
  public static void main(String[] args) throws Exception{

   ScriptEngineManager factory = new ScriptEngineManager();
   ScriptEngine engine = factory.getEngineByName("JavaScript");
   engine.put("cb", new JsCallback());
   engine.eval("println('Doing something in javascript here first');" +
     "cb.apply('bar');");
  }

  public void apply(String s){
    System.out.println("Back in java code here: " + s);
  }
}
cmbaxter
  • 34,269
  • 4
  • 81
  • 93
  • Hi cmbaxter! I'm not sure. In my project I will invoke a javascript function. Then the control will return to java until the callback is executed. This actually prompts another question. What is the lifecycle of the variables on the javascript side? Thanks – Piero May 10 '13 at 01:46
  • 1
    If you are asking about the lifecycle of the Java variable I supplied into the script (bound to `cb`), I believe that Object (the `JsCallback`) won't be garbage collected by Java until that `ScriptEngine` itself (`engine`) is fully dereferenced and available for collection. If you are worried about that `cb` var not being around in js by the time the js gets around to using it, I don't think you need to be. Here's a good link to learn a bit more about some of the inner workings: http://stackoverflow.com/questions/6936223/what-is-the-lifecycle-and-concurrency-semantics-of-rhino-script-engine – cmbaxter May 10 '13 at 10:25
1

Use a Function in Java 8:

JS:

run = function(callback) {
  callback("foo");
}

Java:

Function<String,String> fn = (arg) -> {
  return arg.toUpperCase();
};

// call run(fn)
invokeFunction("run", fn)

You can also use Runnable (no arguments or return values) and probably many other single-method interfaces as callback interfaces. From what I undertand it will try to find a method that matches the argument list dynamically.

Presumably you can use this to bind functions to the scope too.

mogsie
  • 3,637
  • 24
  • 25