Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Java interface from JavaScript fails with a TypeError

I have an interface ru.focusmedia.odp.server.scripts.api.Script and tried to implement it according to the example in http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html:

new Packages.ru.focusmedia.odp.server.scripts.api.Script() {
    ...
};

However, this gives the following exception:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: [JavaPackage ru.focusmedia.odp.server.scripts.api.Script] is not a function, it is sun.org.mozilla.javascript.internal.NativeJavaPackage. (#1) in at line number 1

new Packages.java.lang.Runnable() works. What is the problem?

UPDATE: I initially thought setting thread context class loader fixed this problem, but it reoccurred after minor changes in the script.

like image 862
Alexey Romanov Avatar asked Apr 14 '26 01:04

Alexey Romanov


1 Answers

This is invalid JavaScript:

new Object() {};

It is invoking a function with "new" but fails to terminate the statement, then an open curly brace indicates the start of an object literal (this is valid syntax in Java; it creates an anonymous subclass). The strange thing is that the Rhino interpreter won't complain, but it correctly throws an error in the browser's engine: "SyntaxError: missing ; before statement"

Try writing the implementation using object literal notation:

var impl = {
    run: function() {
        println('Hello, World!');
    }
};

Here's a working example:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class RhinoTest {
    private static final String JAVASCRIPT_SRC = 
            " var impl = { " +
            "     run: function() { " +
            "         println('Hello, World!'); " +
            "     } " +
            " }; ";

    public static void main(String[] args) throws Exception {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        engine.eval(JAVASCRIPT_SRC);

        Object impl = engine.get("impl");
        Runnable r = ((Invocable) engine).getInterface(impl, Runnable.class);
        r.run();
    }
}
like image 61
Joe Coder Avatar answered Apr 15 '26 14:04

Joe Coder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!