为什么在graalvm社区版上使用org.graalvm.polyglot而不是javax.script包?

为什么在graalvm社区版上使用org.graalvm.polyglot而不是javax.script包?,java,graalvm,Java,Graalvm,我有一个java应用程序在java-8-openjdk-amd64上工作,它评估java脚本。现在我安装了GraalVM社区版GraalVM-ce-19.2.0(ubuntu 18.04),并尝试使用org.GraalVM.polyglot.Context 它们是可行的,但当发现旧的java脚本代码崩溃,堆栈跟踪显示它是用org.graalvm包而不是javax.script进行评估时,我感到惊讶: import javax.script.ScriptEngine; ..

我有一个java应用程序在java-8-openjdk-amd64上工作,它评估java脚本。现在我安装了GraalVM社区版GraalVM-ce-19.2.0(ubuntu 18.04),并尝试使用
org.GraalVM.polyglot.Context
它们是可行的,但当发现旧的java脚本代码崩溃,堆栈跟踪显示它是用org.graalvm包而不是javax.script进行评估时,我感到惊讶:

import javax.script.ScriptEngine;
            ...
            ScriptEngine engine = 
            scriptFactory.getEngineByName("JavaScript");
            engine.put("form", postedAnswer);
            engine.put("question", jsQuestion);
            engine.put("answer", jsAnswer);
            engine.eval(validationJS); //here Exception thrown
这里是堆栈跟踪:

javax.script.ScriptException: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (getData) on JavaObject[com.researchforgood.survey.surveyengine.JSQuestion@504641f2 (com.researchforgood.survey.surveyengine.JSQuestion)] failed due to: Unknown identifier: getData
    at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:348)
    at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:323)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
    at com.researchforgood.survey.surveyengine.service.StepService.validateAnswers(StepService.java:233)
    at com.researchforgood.survey.surveyengine.service.StepService.processAnswers(StepService.java:95)
    at com.researchforgood.survey.surveyengine.HttpSurveyHandler.doPost(HttpSurveyHandler.java:160)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at com.researchforgood.api.apigateway.ServletHandler.handle(ServletHandler.java:62)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:205)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:502)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (getData) on JavaObject[com.researchforgood.survey.surveyengine.JSQuestion@504641f2 (com.researchforgood.survey.surveyengine.JSQuestion)] failed due to: Unknown identifier: getData
    at <js>.:program(<eval>:6)
    at org.graalvm.polyglot.Context.eval(Context.java:344)
    at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:346)
    ... 25 more
javax.script.ScriptException:org.graalvm.polyglot.PolyglotException:TypeError:JavaObject[com.researchforgood.surveyengine]上的invokeMember(getData)。JSQuestion@504641f2(com.researchforgood.survey.surveyengine.JSQuestion)]失败,原因是:未知标识符:getData
位于com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:348)
位于com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:323)
位于javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
在com.researchforgood.survey.surveyengine.service.StepService.validateAnswers上(StepService.java:233)
在com.researchforgood.survey.surveyengine.service.StepService.processAnswers上(StepService.java:95)
在com.researchforgood.survey.surveyengine.HttpSurveyHandler.doPost(HttpSurveyHandler.java:160)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
位于com.researchforgood.api.apigateway.ServletHandler.handle(ServletHandler.java:62)
位于org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
位于org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
位于org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
位于org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:205)
位于org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
位于org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
位于org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
位于org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
位于org.eclipse.jetty.server.server.handle(server.java:502)
位于org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
位于org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
位于org.eclipse.jetty.io.AbstractConnection$ReadCallback.successed(AbstractConnection.java:305)
位于org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
位于org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
位于org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
位于org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
运行(Thread.java:748)
原因:org.graalvm.polyglot.polyglot异常:类型错误:JavaObject[com.researchforgood.surveyengine]上的invokeMember(getData)。JSQuestion@504641f2(com.researchforgood.survey.surveyengine.JSQuestion)]失败,原因是:未知标识符:getData
at.:程序(:6)
位于org.graalvm.polyglot.Context.eval(Context.java:344)
位于com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:346)
... 25多
这让我很困惑。我以前从未在JVM中看到过这种行为。这是否意味着Graalvm虚拟机与Java虚拟机不兼容


我看到上面提到的polyglot.js.nashorn-compat属性使polyglot以与nashorn相同的方式工作,但这并不能回答我的问题,因为我没有在崩溃的代码中使用org.graalvm.polyglot。

graalvm/JavaScript是graalvm中用于执行JavaScript代码的JavaScript引擎。它是基于org.graalvm.(polyglot)的,因此您可以在stacktrace中看到,一般来说没有什么需要担心的。出于兼容性原因,GraalVM/JavaScript提供了javax.script的实现,但这只是(首选)org.GraalVM.polyglot.Context的包装器,用于与此类引擎交互

您看到的具体错误可能是由于脚本试图访问默认情况下受GraalVM沙箱限制的资源而导致的。您需要传递其他参数以允许此类访问,例如:

//create engine as in your example, then:
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowAllAccess", true);
engine.eval(validationJS);
再次注意,这可能会增加您的安全攻击面,仅以这种方式(通常使用ScriptEngine)执行受信任的代码

有关更多选项以及如何使用ScriptEngine与GraalVM/JavaScript交互的信息,请参阅

希望这有帮助, 基督教徒