Nashorn运行JavaScript的沙箱。
- 可设置最大的CPU运行时间(防止无限循环等)
- 可设置最大的内存使用限制
- 对可使用的Java类进行过滤
做资源限制,但前提是给沙箱设置ExecutorService
StandardNashornSandbox nashornSandbox = new StandardNashornSandbox();
ExecutorService executorService = Executors.newFixedThreadPool(3);
// limit cpu time (10 seconds)
nashornSandbox.setMaxCPUTime(10 * 1000);
// limit memory (10MB)
nashornSandbox.setMaxMemory(10 * 1024 * 1024);
nashornSandbox.setExecutor(executorService);
nashornSandbox.eval("while(true) { }");
允许脚本中可使用的Java类:
nashornSandbox.allow(Thread.class);
沙箱中只有一个ScriptEngine
实例,多线程下使用eval
时,应该创建新的ScriptContext
实例。
下面例子中省略了异常处理,如果scriptContext
为null
,程序运行结果则是无法预料的:
for (int i = 0; i < 30; i++) {
executorService.execute(() -> {
ScriptContext scriptContext = nashornSandbox.createScriptContext();
nashornSandbox.eval("var j = 0; for (var i = 0; i < 100; i++) { j++ } console.log('j=' + j)", scriptContext);
});
}
CompiledScript compiledScript = nashornSandbox.compile("var j = 0; for (var i = 0; i < 100; i++) { j++ }");
compiledScript.eval();
沙箱默认给Bindings
提供了console
对象,因此可以JavaScript脚本中使用如下api:
console.debug('Hello')
// log同info
console.log('Hello')
console.info('Hello')
console.error('Hello')
console
打印的日志使用Java的slf4j-api
实现,所以用户需要制定自己的日志框架实现。see SLF4J bindings
由于安全限制,语句体必须包裹在双大括号{}
中,即使只有一句
// not allow
if (a > b)
return a - b
// good
if (a > b) {
return a - b
}
maven:
<!-- 即将到来 -->