[英]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函数添加为原型的属性。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.