如何在java脚本中创建ScriptableObject的对象.....?

时间:2011-09-27 10:55:56

标签: java javascript rhino

当我尝试在扩展 ScriptableObject 的java脚本文件中创建类的对象时......将出现以下错误。

js: uncaught JavaScript runtime exception: TypeError: Cannot find default value for object.”

类文件

package sumit2;
import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
public String getClassName(){
    return "Sumit";
}   
public void foo() {
    System.out.println("Sumit!!!!!!!");
}
}

Java脚本文件是: -

importPackage(Packages.sumit2);
var vv=new Sumit();
print(vv.foo());

3 个答案:

答案 0 :(得分:9)

首先,您必须在Sumit中覆盖getDefaultValue。这是从javascript将对象转换为字符串所必需的。

package sumit2;

import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
    public String getClassName(){
        return "Sumit";
    }   
    public void foo() {
        System.out.println("Sumit!!!!!!!");
    }
    @Override
    public Object getDefaultValue(Class<?> typeHint) {
        return toString();
    }

}

然后,您将收到以下错误消息:

js: uncaught JavaScript runtime exception: TypeError: Cannot find function foo in object sumit2.Sumit@1bf6770.

**注意:显示上面的异常时会导致异常“找不到对象的默认值。”字符串值“sumit2.Sumit@1bf6770”是通过调用getDefaultValue生成的

其次,javascript无法调用从ScriptableObject扩展的对象的java方法。如果你想从javascript调用foo,请覆盖get(String,Scriptable),如下所示:

package sumit2;

import jp.tonyu.js.BuiltinFunc;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
    public String getClassName(){
        return "Sumit";
    }   
    public void foo() {
        System.out.println("Sumit!!!!!!!");
    }
    @Override
    public Object getDefaultValue(Class<?> typeHint) {
        return toString();
    }

    @Override
    public Object get(String name, Scriptable start) {
        if ("foo".equals(name)) {
            return new Function() {

                @Override
                public Object call(Context cx, Scriptable scope, Scriptable thisObj,
                        Object[] args) {
                    foo();
                    return "Return value of foo";
                }
                /** ...Implement all methods of Function other than call **/

            };
        }
        return super.get(name, start);
    }


}

你会得到:

Sumit!!!!!!!
Return value of foo

我认为那部分

/** ...Implement all methods of Function other than call **/

很烦人。我建议创建一个实现Function的适配器类,并用空语句覆盖Function的所有方法。

答案 1 :(得分:0)

我尝试使用@ hoge1e3发布的代码概念,但不幸的是,它对我来说不适用于最新的Rhino构建(1_7R5pre)。但是,我能够使用Rhino框架提供的注释创建一个Java类,该类具有可在JavaScript中调用的方法。最后,它实际上非常简单明了。

作为参考,请参阅Mozilla提供的Rhino源代码中包含的示例:https://github.com/mozilla/rhino/tree/master/examples

示例类定义:

//this gives you access to the annotations needed to expose your Java methods and properties to JavaScript
import org.mozilla.javascript.annotations.JSFunction; 

public class Sumit extends ScriptableObject {

    public String getClassName(){
        return "Sumit";
    }   

    @JSFunction
    public void foo() {
        //add in the above annotation and your Java method 'foo' will now be available in JavaScript
        System.out.println("Sumit!!!!!!!");
    }
}

将上述类从Java转换为JavaScript的示例:

//Make sure to define your Context and Scope beforehand
ScriptableObject.defineClass(scope, Sumit.class);

答案 2 :(得分:-2)

代码中存在逻辑错误:您正在尝试打印void值:vv.foo()的返回值。

如果您将代码从print(vv.foo())更改为: vv.foo(),或者更改Java以返回String "Sumit!!!!!!!"并打印出来,我认为您的工作将会有效。