Basically I'm trying to pass a javaScript function to a Java method to
act as a callback to the script.
I can do it - sort of - but the object I receive is a
sun.org.mozilla.javascript.internal.InterpretedFunction and I don't see
a way to invoke it.
Any ideas? BTW currently I'm using Rhino inside Java 6.
Here's what I have so far:
var someNumber = 0;
function start() {
// log is just an log4j instance added to the Bindings
log.info("started....");
someNumber = 20;
// Test is a unit test object with this method on it (taking Object
as a param).
test.callFromRhino(junk);
}
function junk() {
log.info("called back " + someNumber);
}
** JAVA SIDE:
import game.util.FileUtil;
import junit.framework.TestCase;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import javax.script.*;
import java.net.URL;
public class TestRhino extends TestCase {
private static final Logger log =
LogManager.getLogger(TestRhino.class);
private ScriptEngineManager mgr = new ScriptEngineManager();
private ScriptEngine engine = mgr.getEngineByName("JavaScript");
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testCallback() {
try {
URL url = getClass().getResource("/callback.js");
String contents = FileUtil.getFileContents(url.getFile());
Compilable compilingEngine = (Compilable) engine;
CompiledScript script = compilingEngine.compile(contents);
Bindings bindings =
engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("log", log);
bindings.put("test", this);
script.eval(bindings);
Invocable invocable = (Invocable) script.getEngine();
invocable.invokeFunction("start");
} catch (Exception e) {
log.error(e.getMessage(), e);
fail(e.getMessage());
}
}
public void callFromRhino(Object callback) {
// how could I call back to this function?
log.info(callback.getClass().getName());
}
}
On 16/05/2010 9:36 AM, Dan Howard wrote:
> Basically I'm trying to pass a javaScript function to a Java method to
> act as a callback to the script.
...
> public void callFromRhino(Object callback) {
Don't make this take an Object. Instead, have it take an interface with
a single method on it whose signature matches the desired JS function.
For example:
interface EventCallback {
void eventOccurred(int eventType);
}
public void callFromRhino(EventCallback callback) {
// some time later you might call callback.eventOccurred(123)
}
and then in JS you can do:
function junk(eventType) { ... }
test.callFromRhino(junk);
In your example it looks like you don't have any parameters in your
callback function, so you could just use a Runnable:
public void callFromRhino(Runnable callback) {
// some time later you might call callback.run()
}