osc*_*enk 8 javascript java rhino
我正在调用一个带@JSFunction注释的方法ScriptableObject
JavaScript文件
Target = Packages.com.acme.rhino.Target;
function evaluate() {
var t = Target();
t.addModifier("foobar", 1);
return t;
}
Run Code Online (Sandbox Code Playgroud)
Java文件
public class Target extends ScriptableObject {
private static final long serialVersionUID = 1L;
public List<Modifier> modifiers = new LinkedList<>();
@JSConstructor
public Target() {
}
@JSFunction
public void addModifier(final String message, final int value) {
modifiers.add(new Modifier(message, value));
}
public int getValue() {
int sum = 0;
for (final Modifier modifier : modifiers) {
sum += modifier.getValue();
}
return sum;
}
@Override
public String getClassName() {
return "Target";
}
}
Run Code Online (Sandbox Code Playgroud)
但我明白了
org.mozilla.javascript.EcmaError: TypeError: Cannot find default value for object.
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3687)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3665)
at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3693)
at org.mozilla.javascript.ScriptRuntime.typeError1(ScriptRuntime.java:3705)
at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:976 )
at org.mozilla.javascript.ScriptableObject.getDefaultValue(ScriptableObject.java:895 )
at org.mozilla.javascript.ScriptRuntime.toString(ScriptRuntime.java:761)
at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3774)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime. java:2269)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime. java:2251)
at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:83)
at org.mozilla.javascript.gen.script_5._c_evaluate_1(script:6)
at org.mozilla.javascript.gen.script_5.call(script)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
at org.mozilla.javascript.gen.script_5.call(script)
Run Code Online (Sandbox Code Playgroud)
而且不知道从哪里去.当我不调用addModifier给定代码的方法,并且notFunctionError在堆栈跟踪中给出错误时,我认为Rhino不会将给定方法解释为JavaScript函数.
可以在此处找到重现错误的完整Maven项目
上述方法的问题是Target.prototype在脚本范围内没有正确设置。ScriptableObject.defineClass()有关如何在脚本作用域中正确定义原型的详细信息,请参阅静态方法。
您有几种选择可以为Target脚本提供构造函数。第一种选择是始终Target为所有脚本定义构造函数。如果您提前知道您希望在Target全球范围内可用,那么这种方法很有效。这基本上可以归结为以下几点:
final Context context = Context.enter();
try {
final ScriptableObject scope = context.initStandardObjects();
ScriptableObject.defineClass(scope, Target.class, false, true);
context.evaluateString(scope, script, "script", 1, null);
// etc.
} finally {
Context.exit();
}
Run Code Online (Sandbox Code Playgroud)
如果您希望脚本作者决定哪些构造函数是必需的,则第二种选择是向脚本提供该defineClass函数。通过此功能,脚本作者可以“导入”其类路径上的任何可编写脚本的对象(这可能超出您允许的范围)。要向脚本提供defineClass功能,请在进入上下文后执行以下操作:
final Context context = Context.enter();
try {
final ScriptableObject scope = context.initStandardObjects();
scope.defineFunctionProperties(
new String[] {"defineClass"},
Global.class,
ScriptableObject.DONTENUM);
context.evaluateString(scope, script, "script", 1, null);
// etc.
} finally {
Context.exit();
}
Run Code Online (Sandbox Code Playgroud)
Target然后,JavaScript 作者通过以下方式使用构造函数:
defineClass("com.acme.rhino.Target");
// whatever `getClassName()` returns is now available
var target = new Target();
Run Code Online (Sandbox Code Playgroud)
在上述两个分支中,我做了一些其他更改,如果您向Target构造函数添加更多内容,这些更改可以让您更好地进行设置。零参数构造函数不需要注释@JSConstructor。如果您稍后想要一个接受参数的构造函数,则此零参数构造函数将用作原型构造函数,并且您可以@JSConstructor在用于初始化对象的方法上使用该注释。根据您编写此构造函数方法的方式,new在 JavaScript 中使用关键字将变得很重要。
简而言之,该Packages.com.acme...语法对于从脚本访问构造函数没有ScriptableObject用。