【问题标题】:Sandboxed java scripting replacement for NashornNashorn 的沙盒 Java 脚本替换
【发布时间】:2020-03-23 18:08:40
【问题描述】:

我一直在使用 Nashorn 进行类似 awk 的批量数据处理。这个想法是,有很多传入的数据,一行一行地,一个接一个。每一行都由命名字段组成。这些数据由存储在外部某处且可由用户编辑的用户定义脚本处理。脚本很简单,例如 if( c>10) a=b+3,其中 a、b 和 c 是传入数据行中的字段。数据量真的很大。代码是这样的(展示用例的例子):

    ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
            new String[]{"-strict", "--no-java", "--no-syntax-extensions", "--optimistic-types=true"},
            null,
            scr -> false);

    CompiledScript cs;
    Invocable inv=(Invocable) engine;
    Bindings bd=engine.getBindings(ScriptContext.ENGINE_SCOPE);

    bd.remove("load");
    bd.remove("loadWithNewGlobal");
    bd.remove("exit");
    bd.remove("eval");
    bd.remove("quit");

    String scriptText=readScriptText();

    cs = ((Compilable) engine).compile("function foo() {\n"+scriptText+"\n}");
    cs.eval();


    Map params=readIncomingData();

    while(params!=null)
    {
        Map<String, Object> res = (Map) inv.invokeFunction("foo", params);
        writeProcessedData(res);
        params=readIncomingData();
    }

现在 nashorn 已经过时了,我正在寻找替代品。谷歌搜索了几天,但没有找到完全符合我的需求。要求是:

  • 速度。有很多数据,所以它应该非常快。所以我也认为,预编译是必须的
  • 应在 linux/openJDK 下工作
  • 至少在数据访问/代码执行方面支持沙盒

很高兴拥有:

  • 简单的类 c 语法(不是 lua;)
  • 支持沙盒处理 CPU 使用率

到目前为止,我发现 Rhino 仍然存在(最后一次发布日期为 2020 年 1 月 13 日),但我不确定它是否仍然受支持以及它有多快 - 我记得,Java 切换到 Nashorn 的原因之一是速度。就我而言,速度非常重要。还找到了 J2V8,但不支持 linux。 GraalVM 看起来有点矫枉过正,还没有得到如何使用它来完成这样的任务 - 如果它适合的话,可能需要进一步探索,但看起来它是完整的 jvm 替代品,不能用作库。

不是必须是javascript,也许还有其他选择。 谢谢。

【问题讨论】:

标签: java performance sandbox embedding


【解决方案1】:

GraalVM 的 JavaScript 可用作库,其依赖项可作为任何 Maven 工件获得。虽然推荐的运行方式是使用 GraalVM 发行版,但有一些解释 how to run it on OpenJDK

您可以限制脚本应该有权访问的内容,例如 Java 类、创建线程等:

来自documentation

The following access parameters may be configured:

* Allow access to other languages using allowPolyglotAccess.
* Allow and customize access to host objects using allowHostAccess.
* Allow and customize host lookup to host types using allowHostLookup.
* Allow host class loading using allowHostClassLoading.
* Allow the creation of threads using allowCreateThread.
* Allow access to native APIs using allowNativeAccess.
* Allow access to IO using allowIO and proxy file accesses using fileSystem.

而且它比 Nashorn 快几倍。例如,可以在article 中找到一些测量值:

GraalVM CE provides performance comparable or superior to Nashorn with 
the composite score being 4 times higher. GraalVM EE is even faster. 

【讨论】:

  • 感谢奥列格的帮助。你真的帮了我很多。已经找到所有关于访问等的内容。现在唯一的问题是,在 1000 万次迭代中运行的测试用 nashorn 持续 4 秒,用 graaljs 持续 20 秒(使用他们的 pom 示例)。估计是编译器使用问题,以后再试
  • 随着我对它的深入了解,它并不是一个简单的替代品。 graal js脚本和java代码之间的数据交换真的很难
猜你喜欢
  • 1970-01-01
  • 2017-07-20
  • 2013-05-09
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多