views:

46

answers:

0

Invoking on a child a method defined in parent, where parent is a host object, gives EcmaError: method called on incompatible object.

Host object defined in Java:

public class HostObject extends ScriptableObject {            

    public HostObject() {}

    @Override
    public String getClassName() {
        return "HostObject";
    }

    public void jsFunction_sayHi() { 
        System.out.println("Hi!");
    }
}

Test script #1 run in Rhino:

var foo = new HostObject();
foo.sayHi();

Works fine.

Test script #2:

function Bar() {}
Bar.prototype = new HostObject();
var bar = new Bar();
bar.sayHi();

Throws an exception:

org.mozilla.javascript.EcmaError: TypeError: Method "sayHi" called on incompatible object.

Found a way around this issue (kind of...) - by using an alternative form of defining a method - a static method with parameters (Context cx, Scriptable thisObj, Object[] args, Function funObj) and then explicitly using the prototype whenever I need to access members:

HostObject ho = (HostObject)thisObj.getPrototype();

Thing is there are situations when sayHi() is invoked on the original object and then getPrototype() refers to Javascript Object, so I would need to perform an extra check to make this work in both cases. I would've thought that with prototype chaining the original example should work just fine. Is that a possible bug here? Or am I doing something wrong?

I'm using Rhino 1.7R2.