I'm trying to write a Java API that will be called from server side JavaScript running under the JDK 7 JS engine. The idea is to give consumers the ability to write JS code like below, registering a callback that is later executed by another call to a Java method:
myJavaObj.registerCallback(function (param) {
// do stuff here
});
myJavaObj.methodThatTriggersCallback();
Here is some test code I'm using:
import javax.script.Invocable;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JSTestClient {
private String successCallback;
public void handleSuccess(String successCallback) {
this.successCallback = successCallback;
}
public void doStuff() throws ScriptException, NoSuchMethodException {
ScriptEngineManager manager = new ScriptEngineManager();
Invocable engine = (Invocable) manager.getEngineByName("JavaScript");
engine.invokeFunction(successCallback, "TEST SUCCESS");
}
}
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Main {
public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String js =
"var client = new Packages.JSTestClient();\n" +
"client.handleSuccess(function (response) {\n" +
" java.lang.System.out.println(response);\n" +
"});\n" +
"client.doStuff();";
try {
engine.eval(js); // Expecting this to output "TEST SUCCESS"
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
But when I run this I get a java.lang.NoSuchMethodException because it is interpreting the string:
function (response) {
java.lang.System.out.println(response);
} as a function name. Is there a way to create a callback like this or do I need to use some other convention?
getEngineByName("JavaScript"), like question code does, you do get a javascript engine back.