【发布时间】:2014-01-27 22:18:34
【问题描述】:
我一直在努力解决使用 java 脚本 API 来控制某些用户定义的 javascript 的执行的问题。我在引擎盖下使用内置的 Rhino 引擎,它说您可以设置 InstructionObserverThreshold ,如果达到限制,它将负责停止执行。我一直在玩下面的示例应用程序一段时间,我很困惑为什么它不起作用。你会看到我也设置了MaximumInterpreterStackDepth。这完美地工作,但指令观察者似乎没有做任何事情。
关于此代码缺少什么以使其正常工作的任何想法?
谢谢!
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.sun.script.javascript.RhinoScriptEngine;
public class RhinoTester2 {
public static void main(String[] args) {
new RhinoScriptEngine(); // initialize the global context.
sun.org.mozilla.javascript.internal.ContextFactory cx = sun.org.mozilla.javascript.internal.ContextFactory.getGlobal();
cx.addListener( new sun.org.mozilla.javascript.internal.ContextFactory.Listener() {
public void contextCreated( sun.org.mozilla.javascript.internal.Context cxt ) {
cxt.setInstructionObserverThreshold(10000 ); // This should stop after 10 seconds or so.
cxt.setMaximumInterpreterStackDepth(1); // this should not be a factor for the moment
System.out.println("Context Factory threshold set. "+cxt.getInstructionObserverThreshold());
}
@Override
public void contextReleased(
sun.org.mozilla.javascript.internal.Context arg0) {
System.out.println("Context Released.");
}
});
// Now run the script to see if it will be stopped after a short time.
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("javascript");
try {
// engine.eval("while(true){println(\"hello\");};"); // This will fail immediately due to the interpreter stack depth.
engine.eval("while(true){};"); // this never fails. runs happily forever.
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
【问题讨论】:
-
不幸的是,脚本 api 使用的基本 ContextFactory 中似乎没有提供处理 InstructionObservationCount 的推荐方法。在查看 RhinoScriptEngine 时,用户无法修改 ContextFactory 以添加实现(密封类和匿名静态块调用 initGlobal)。据我所知,只有两个选项 - 创建自己的脚本引擎并替换内置版本,或者在线程中管理它并在超过超时时终止线程。令人失望.....
标签: java javascript rhino javax.script