繁体   English   中英

mozilla rhino从javascript覆盖对象方法

[英]mozilla rhino overriding an object method from javascript

我正在寻找从rhino中的javascript覆盖java方法。 这是我的代码:

public class CustomClass {
public String s="some string";
public void doSomething(){}
}

接着:

        Object wrappedOut = Context.javaToJS(new CustomClass(), scope);
        ScriptableObject.putProperty(scope, "CustomClass", wrappedOut);
        String s="CustomClass.s='aaa'; \n CustomClass.doSomething=function(args){};";
        Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);

因此可以将值更改为CustomClass.s,但不能更改为doSomething方法

我收到以下错误:

org.mozilla.javascript.EvaluatorException:无法将Java方法“doSomething”分配给。 (#2)

更新根据评论中的要求,这是我的完整源代码:

CustomClass.java

public class CustomClass {
    public String s="Do something now!";

    public void doSomething(Object ... v){
        System.out.println("do something");
    }
}

Scripting.java

import org.mozilla.javascript.*;
public class Scripting {
    public static void main(String args[])
    {

        Context cx = Context.enter();
        try {

            Scriptable scope = cx.initStandardObjects();

            Object wrappedOut = Context.javaToJS(new CustomClass(), scope);
            ScriptableObject.putProperty(scope, "CustomClass", wrappedOut);


            String s="CustomClass.doSomething=function(args){};";

            Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);

            System.err.println(Context.toString(result));
        }catch(WrappedException e){
            e.printStackTrace();

        } catch(Exception e){
            e.printStackTrace();
        }finally {
            // Exit from the context.
            Context.exit();
        }
    }
}

当此代码运行时,Rhino不会调用Java doSomething方法。 相反,它尝试调用其javascript对应 (缺少),然后抛出sun.org.mozilla.javascript.internal.EvaluatorException: Java class "CustomClass" has no public instance field or method named "doSomething". (#1) sun.org.mozilla.javascript.internal.EvaluatorException: Java class "CustomClass" has no public instance field or method named "doSomething". (#1)例外。

您的CustomClass是纯Java类,没有JavaScript对应。 如果您在源中替换此行:

String s="CustomClass.doSomething=function(args){};";

用这一行:

String s = "CustomClass";

并将其评估为CustomClass@15e0be38命令,它将输出为CustomClass@15e0be38 这通常意味着它是一些(“15e0be38”)类的对象的实例CustomClass

从apidoc for方法ScriptableObject.defineClass(Scriptable scope, java.lang.Class clazz)


从实现Scriptable的Java类定义JavaScript对象。
(......)
接下来,扫描所有方法以获取特殊前缀,这些前缀表明它们对于定义JavaScript对象具有特殊意义。 这些特殊的前缀是

jsFunction_用于JavaScript函数
jsStaticFunction_用于JavaScript函数,它是构造函数的属性
jsGet_用于获取JavaScript属性的getter
jsSet_用于JavaScript属性的setter
作为构造函数的JavaScript函数的jsConstructor

如果方法的名称以“jsFunction_”开头,则创建一个JavaScript函数,其名称由“jsFunction_”之后的其余Java方法名称组成。 因此,名为“jsFunction_foo”的Java方法将定义JavaScript方法“foo”。 调用此JavaScript函数将导致调用Java方法。 方法的参数必须是FunctionObject类定义的数量和类型。 然后将JavaScript函数添加为原型的属性。


JavaScript print方法((在org.mozilla.javascript.tools.shell.Global类中定义))与Java System.out.println方法的接口。 跑步时

 public class CustomClass { public static class _CustomClass extends ScriptableObject { @Override public String getClassName() { return "CustomClass"; } public int jsFunction_method() { System.out.println("from java method"); return 2; } } public static void main(String[] args) { Context context = Context.enter(); Global global = new Global(context); try { //ScriptableObject.defineClass(global, CustomClass.class); ScriptableObject.defineClass(global, _CustomClass.class); String script = "myInstance = new CustomClass();myInstance+' ';"; System.out.println(context.evaluateString(global, script, "", 1, null)); script = "myInstance.method+' '+myInstance.method()"; System.out.println(context.evaluateString(global, script, "script", 1, null)); script = "CustomClass.prototype.method=function(){print('overriden from javascript method');return 3;}"; context.evaluateString(global, script, "", 1, null); script = "myInstance.method+' '+myInstance.method();"; System.out.println(context.evaluateString(global, script, "script", 1, null)); } catch (Exception e) { e.printStackTrace(); } finally { Context.exit(); } } } 

它输出:

 [object CustomClass] from java method function method() { [native code, arity=0] } 2 overriden from javascript method function () { print("overriden from javascript method"); return 3; } 3 
  • 请注意,如果在Chrome中运行相同的JS代码,它将以不同的方式运行 - 返回2两次。
  • 如果外部类已被使用(如在注释中),则会出现通用的相关编译时错误。 此代码是使用Rhino 1.7r2编写的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM