Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can I pass a javaScript function to a Java Method to act as a callback

705 views
Skip to first unread message

Dan Howard

unread,
May 15, 2010, 7:36:54 PM5/15/10
to
Hi everyone,

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());
}
}

Cameron McCormack

unread,
May 16, 2010, 12:37:55 AM5/16/10
to
Hi Dan.

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()
}

Dan Howard

unread,
May 16, 2010, 6:41:55 AM5/16/10
to
Wow that's cool. Thanks!
0 new messages