GraalJS - 无法从 jar 构建 ScriptEngine
GraalJS - Cannot build ScriptEngine from jar
我遇到了一个涉及 GraalJS 的问题。我正在尝试将其用作我的 JavaScript 后端。当我从 IntelliJ 中 运行 时,它可以完美地工作,但是一旦我导出 运行nable .jar,它就会停止工作。我已经调试这个问题几天了,以下是我的发现。
应该提到的是,我通过使用 gradle 命令生成我的 运行nable .jar,该命令与 libGdx 一起打包,名为 desktop:dist.
首先,这些是我使用的依赖项
// 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
试图为选项名称 js
找到 PolyglotLanguage
时会发生这种情况。事实证明,这是 IntelliJ 和来自 运行nable .jar 的 运行ning 之间的区别。 IntelliJ 包含对 JavaScript PolyglotLanguage
的支持,而 .jar 不支持。这是我发现的
通过查看 Engine -> impl -> idToLanguage
(我通过反射访问了这些包私有字段)我得到以下结果
Intellij :
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
匹配时,会发生异常。
我不确定如何进行或为什么会发生这种情况。也许是关于类加载器的?无论哪种方式,我们都将不胜感激
以下link回答了我的问题:https://github.com/oracle/graaljs/issues/125
事实证明,在 .jar 打包过程中,REGEX 和 Javascript 的 PolyglotLanguage 条目以某种方式被覆盖。这意味着您必须在 META-INF/truffle/language
处的 .jar 中创建一个文件,并添加答案中的内容。请注意,对我来说 github link 中的内容 完全 没用。我需要将它们更改为
#https://github.com/graalvm/graaljs/issues/125
language2.characterMimeType.0=application/javascript
language2.characterMimeType.1=application/javascript+module
language2.characterMimeType.2=text/javascript
language2.className=com.oracle.truffle.js.lang.JavaScriptLanguage
language2.defaultMimeType=application/javascript
language2.dependentLanguage.0=regex
language2.fileTypeDetector0=com.oracle.truffle.js.lang.JSFileTypeDetector
language2.id=js
language2.implementationName=GraalVM JavaScript
language2.interactive=true
language2.internal=false
language2.name=JavaScript
language2.version=inherit
我遇到了一个涉及 GraalJS 的问题。我正在尝试将其用作我的 JavaScript 后端。当我从 IntelliJ 中 运行 时,它可以完美地工作,但是一旦我导出 运行nable .jar,它就会停止工作。我已经调试这个问题几天了,以下是我的发现。
应该提到的是,我通过使用 gradle 命令生成我的 运行nable .jar,该命令与 libGdx 一起打包,名为 desktop:dist.
首先,这些是我使用的依赖项
// 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
试图为选项名称 js
找到 PolyglotLanguage
时会发生这种情况。事实证明,这是 IntelliJ 和来自 运行nable .jar 的 运行ning 之间的区别。 IntelliJ 包含对 JavaScript PolyglotLanguage
的支持,而 .jar 不支持。这是我发现的
通过查看 Engine -> impl -> idToLanguage
(我通过反射访问了这些包私有字段)我得到以下结果
Intellij :
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
匹配时,会发生异常。
我不确定如何进行或为什么会发生这种情况。也许是关于类加载器的?无论哪种方式,我们都将不胜感激
以下link回答了我的问题:https://github.com/oracle/graaljs/issues/125
事实证明,在 .jar 打包过程中,REGEX 和 Javascript 的 PolyglotLanguage 条目以某种方式被覆盖。这意味着您必须在 META-INF/truffle/language
处的 .jar 中创建一个文件,并添加答案中的内容。请注意,对我来说 github link 中的内容 完全 没用。我需要将它们更改为
#https://github.com/graalvm/graaljs/issues/125
language2.characterMimeType.0=application/javascript
language2.characterMimeType.1=application/javascript+module
language2.characterMimeType.2=text/javascript
language2.className=com.oracle.truffle.js.lang.JavaScriptLanguage
language2.defaultMimeType=application/javascript
language2.dependentLanguage.0=regex
language2.fileTypeDetector0=com.oracle.truffle.js.lang.JSFileTypeDetector
language2.id=js
language2.implementationName=GraalVM JavaScript
language2.interactive=true
language2.internal=false
language2.name=JavaScript
language2.version=inherit