我们在应用程序中使用GraalVM.js作为ScriptEngine。目标是拥有一个可以运行用户定义的javascript脚本来扩展功能的Java。
MVCE:
ScriptEngine engine = GraalJSScriptEngine.create(null, Context.newBuilder("js"));
String script = "6 * 7";
Object eval = ((Compilable) engine).compile(script).eval();
System.out.println(eval);
代码整齐地打印"42“,而不是在这个冗长的警告之前:
[To redirect Truffle log output to a file use one of the following options:
* '--log.file=<path>' if the option is passed using a guest language launcher.
* '-Dpolyglot.log.file=<path>' if the option is passed using the host Java launcher.
* Configure logging using the polyglot embedding API.]
[engine] WARNING: The polyglot context is using an implementation that does not support runtime compilation.
The guest application code will therefore be executed in interpreted mode only.
Execution only in interpreted mode will strongly impact the guest application performance.
For more information on using GraalVM see https://www.graalvm.org/java/quickstart/.
To disable this warning the '--engine.WarnInterpreterOnly=false' option or use the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
我试着遵循印刷的建议:
ScriptEngine engine = GraalJSScriptEngine.create(null, Context.newBuilder("js")
.option("engine.WarnInterpreterOnly","false")
);
不幸的是,除了一个例外,这是失败的:
Exception in thread "main" java.lang.IllegalArgumentException: Option engine.WarnInterpreterOnly is an engine option. Engine level options can only be configured for contexts without a shared engine set. To resolve this, configure the option when creating the Engine or create a context without a shared engine.
at com.oracle.truffle.polyglot.PolyglotEngineException.illegalArgument(PolyglotEngineException.java:131)
at com.oracle.truffle.polyglot.PolyglotContextConfig.findObjectForContextOption(PolyglotContextConfig.java:433)
at com.oracle.truffle.polyglot.PolyglotContextConfig.<init>(PolyglotContextConfig.java:260)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.createContext(PolyglotEngineImpl.java:1697)
at com.oracle.truffle.polyglot.PolyglotEngineDispatch.createContext(PolyglotEngineDispatch.java:159)
at org.graalvm.polyglot.Context$Builder.build(Context.java:1837)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createDefaultContext(GraalJSScriptEngine.java:353)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.initContext(GraalJSBindings.java:91)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.requireContext(GraalJSBindings.java:86)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.entrySet(GraalJSBindings.java:172)
at java.base/java.util.AbstractMap.containsKey(AbstractMap.java:144)
at java.scripting/javax.script.SimpleScriptContext.getAttribute(SimpleScriptContext.java:158)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createSource(GraalJSScriptEngine.java:450)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:628)
at Scratch.main(scratch_1.java:17)
Process finished with exit code 1
我不知道这个异常意味着什么以及如何解决它。添加VM选项是不切实际的,而文档承诺应该可以传递这样的选项:https://www.graalvm.org/22.0/reference-manual/polyglot-programming/#passing-options-programmatically
log选项根本不起作用:
ScriptEngine engine = GraalJSScriptEngine.create(null, Context.newBuilder("js")
.option("log.file","log\\engine.log")
);
结果:
Exception in thread "main" java.lang.IllegalArgumentException: log.file
at com.oracle.truffle.polyglot.PolyglotEngineException.illegalArgument(PolyglotEngineException.java:131)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.parseLoggerName(PolyglotEngineImpl.java:776)
at com.oracle.truffle.polyglot.PolyglotContextConfig.<init>(PolyglotContextConfig.java:257)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.createContext(PolyglotEngineImpl.java:1697)
at com.oracle.truffle.polyglot.PolyglotEngineDispatch.createContext(PolyglotEngineDispatch.java:159)
at org.graalvm.polyglot.Context$Builder.build(Context.java:1837)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createDefaultContext(GraalJSScriptEngine.java:353)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.initContext(GraalJSBindings.java:91)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.requireContext(GraalJSBindings.java:86)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.entrySet(GraalJSBindings.java:172)
at java.base/java.util.AbstractMap.containsKey(AbstractMap.java:144)
at java.scripting/javax.script.SimpleScriptContext.getAttribute(SimpleScriptContext.java:158)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createSource(GraalJSScriptEngine.java:450)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:628)
at Scratch.main(scratch_1.java:17)
依赖关系:
<!-- https://mvnrepository.com/artifact/org.graalvm.sdk/graal-sdk -->
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>22.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js -->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>22.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js-scriptengine -->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>22.2.0</version>
</dependency>
有什么建议吗?
发布于 2022-08-26 08:10:14
您可以使用上下文eval而不是ScriptEngine,这使得性能方面的检查更慢-- https://www.graalvm.org/22.2/reference-manual/js/FAQ/#warning-implementation-does-not-support-runtime-compilation
下面的代码在没有警告的情况下为我工作。
public static void main(String[] args) {
Engine engine = Engine.newBuilder()
.option("engine.WarnInterpreterOnly", "false")
.build();
Context ctx = Context.newBuilder("js").engine(engine).build();
String script = "6 * 7";
Object eval = ctx.eval("js", script);
System.out.println(eval);
}
在intellij中,输出如下所示
https://stackoverflow.com/questions/73445276
复制相似问题