我遇到了一个涉及 GraalJS 的问题。我正在尝试将它用作我的 JavaScript 后端。当我从 IntelliJ 运行时,它可以完美运行,但是一旦我导出可运行的 .jar,它就会停止工作。这几天我一直在调试这个问题,下面是我的发现。
应该提到的是,我通过使用与 libGdx 一起打包的名为 desktop:dist 的 gradle 命令生成可运行的 .jar。
首先,这些是我使用的依赖项
// GraalVM
compile group: 'org.graalvm.js', name: 'js', version: '20.2.0'
compile group: 'org.graalvm.js', name: 'js-scriptengine', version: '20.2.0'
compile group: 'org.graalvm.sdk', name: 'graal-sdk', version: '20.2.0'
compile group: 'org.graalvm.truffle', name: 'truffle-api', version: '20.2.0'
implementation 'com.ibm.icu:icu4j:51.1'
这就是我构建 ScriptEngine 的方式
private fun getGraalEngine() = GraalJSScriptEngine.create(
Engine.newBuilder()
.allowExperimentalOptions(false)
.useSystemProperties(false)
.build(),
Context.newBuilder("js")
.allowHostAccess(HostAccess.ALL)
.allowHostClassLookup { true }
.allowAllAccess(true))
现在,当我从 .jar 运行程序时,我得到了这个异常:
java.lang.IllegalArgumentException: Could not find option with name js.script-engine-global-scope-import.
at com.oracle.truffle.polyglot.PolyglotEngineException.illegalArgument(PolyglotEngineException.java:128)
at com.oracle.truffle.polyglot.OptionValuesImpl.failNotFound(OptionValuesImpl.java:283)
at com.oracle.truffle.polyglot.PolyglotContextConfig.findLanguageForOption(PolyglotContextConfig.java:239)
at com.oracle.truffle.polyglot.PolyglotContextConfig.<init>(PolyglotContextConfig.java:129)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.createContext(PolyglotEngineImpl.java:1434)
at org.graalvm.polyglot.Context$Builder.build(Context.java:1598)
经过一些调试,我得出的结论是,当PolyglotContextConfig
尝试PolyglotLanguage
为 optionName找到 a 时会发生这种情况js
。事实证明,这是 IntelliJ 与从可运行的 .jar 运行之间的区别。IntelliJ 包含对 JavaScript 的支持PolyglotLanguage
,而 .jar 不包含。这是我发现的
通过查看Engine -> impl -> idToLanguage
(我通过反射访问了这些包私有字段),我得到以下结果
智能:
id to lang: {regex=PolyglotLanguage [id=regex, name=REGEX, host=false], js=PolyglotLanguage [id=js, name=JavaScript, host=false]}
可运行的.jar:
id to lang: {regex=PolyglotLanguage [id=regex, name=REGEX, host=false]}
原来对 JavaScript 的支持只是……错过了?因此,当PolyglotContextConfig.findLanguageForOption()
尝试将js
optionName 与匹配时JavaScript PolyglotLanguage
,会发生异常。
我不确定如何进行或为什么会发生这种情况。也许关于类加载器的东西?无论哪种方式,任何帮助将不胜感激