You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraalJS打包为可运行jar包后无法构建ScriptEngine问题求助

问题解决方案

根因定位

你遇到的问题本质是libGDX默认的fatJar打包逻辑存在服务注册文件合并冲突:
GraalVM系列组件依赖Java SPI机制注册语言实现,所有语言的注册信息都存放在各依赖jar包的META-INF/services/org.graalvm.polyglot.LanguageProvider路径下。libGDX的desktop:dist任务默认不会合并同名SPI配置文件,只会保留最后一个加载的jar包对应的配置,导致GraalJS的语言注册信息被覆盖,运行时无法识别js语言。

解决方案

  • 第一步:修改desktop模块的build.gradle打包配置,添加SPI服务文件合并规则
    在desktop模块的build.gradle中找到jar任务配置,添加mergeServiceFiles()配置,示例如下:
jar {
    // 原有配置保留,添加如下内容
    mergeServiceFiles()
    // 可选:排除存在冲突的重复非必要文件
    exclude 'META-INF/*.DSA'
    exclude 'META-INF/*.RSA'
    exclude 'META-INF/*.SF'
}

如果你的项目用的是shadowJar插件打包,对应配置如下:

shadowJar {
    mergeServiceFiles()
}
  • 第二步:显式指定Graal Context的类加载器
    修改ScriptEngine构建代码,在Context构建时显式传入上下文类加载器,避免打包后类加载器异常:
private fun getGraalEngine() = GraalJSScriptEngine.create(
    Engine.newBuilder()
        .allowExperimentalOptions(false)
        .useSystemProperties(false)
        .build(),
    Context.newBuilder("js")
        .allowHostAccess(HostAccess.ALL)
        .allowHostClassLookup { true }
        .allowAllAccess(true)
        // 新增行:指定当前线程上下文类加载器
        .serverClassLoader(Thread.currentThread().contextClassLoader)
)
  • 第三步:打包后验证
    导出jar包后,解压检查META-INF/services/org.graalvm.polyglot.LanguageProvider文件,确认存在org.graalvm.js.lang.JsLanguageProvider条目即可。

内容的提问来源于stack exchange,提问作者Mihai Fumarel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 00:15:04