Question

I'm trying to write JavaScript that will define a class that extends an existing Java class, called from a JSR223 ScriptEngine. I know that JavaAdapter works for an Interface, but not a Class.

ScriptEngine js = new ScriptEngineManager().getEngineByExtension("js");
js.eval("new java.lang.Runnable {run: function() { ... } }"); // works
js.eval("new java.util.TimerTask {run: function() { ... } }"); // throws

I know that's what the docs say I should expect. I also know that once I can switch to Nashorn, all this will go away and I'll have lovely access to Java.extend(), etc., but for the time being I'm stuck with JDK7.

Given all that, is there any way to do this? I think my fallback will be switching directly to Mozilla's native Rhino bindings, but I'd prefer to keep this as abstract as possible.

Was it helpful?

Solution 2

I think I've figured it out. I was under the impression that I could only implement an interface, but it turns out that you can also extend a concrete class -- only abstract classes throw the error I described.

ScriptEngine js = new ScriptEngineManager().getEngineByExtension("js");
js.eval("new java.lang.Runnable() {run: function() { ... } }"); // works
js.eval("new java.lang.Thread() {run: function() { ... } }"); // works
js.eval("new java.util.TimerTask() {run: function() { ... } }"); // throws

This is good enough for my needs -- the docs could definitely be clearer, though!

OTHER TIPS

What does it throw?

jjs> var tt = new java.util.TimerTask {run: function() { print("hello"); }}
jjs> tt.run();
hello
null

I usually skip TimerTask altogether

// Daemon flag seems to be ignored.
var timer = new java.util.Timer(false);
timer.schedule(function() print("Hello"), 1000);

// Give timer a chance to run before exit.
java.lang.Thread.sleep(5000);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top