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

JavaFX打包Jar在部分Linux和MacOS运行失败:Glass工厂类加载错误

问题:JavaFX打包Jar在部分MacOS和Linux系统无法运行

我用IntelliJ打包了一个Jar文件,在Windows和部分MacOS系统能正常运行,但在部分MacOS和Linux系统启动失败。

已尝试操作

  • 将JavaFX版本从17降级至11
  • 添加了module-info.java并引入JavaFX Controls与FXML模块

build.gradle 内容

plugins {
    id 'checkstyle'
    id 'java'
    id 'application'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
    id 'org.openjfx.javafxplugin' version '0.0.13'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0'
    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0'

    String javaFxVersion = '17.0.8'

    implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win'
    implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac'
    implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux'
    implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win'
    implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac'
    implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux'
    implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win'
    implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac'
    implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux'
    implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
    implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
    implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'

}

test {
    useJUnitPlatform()

    testLogging {
        events "passed", "skipped", "failed"

        showExceptions true
        exceptionFormat "full"
        showCauses true
        showStackTraces true
        showStandardStreams = false
    }
}

javafx {
    version = '17'
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

application {
    mainClass.set("seedu.Launcher")
}

shadowJar {
    archiveBaseName = "duke"
    archiveClassifier = null
    dependsOn("distZip", "distTar")
}

checkstyle {
    toolVersion = '10.2'
}

run {
    standardInput = System.in
}

报错信息

2023年9月16日 00:08:25 com.sun.javafx.application.PlatformImpl startup
警告:不支持的JavaFX配置:类从“未命名模块@6712f432”加载
java.lang.ClassNotFoundException: com.sun.glass.ui.gtk.GtkPlatformFactory
        在 java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        在 java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        在 java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
        在 java.base/java.lang.Class.forName0(Native Method)
        在 java.base/java.lang.Class.forName(Class.java:315)
        在 com.sun.glass.ui.PlatformFactory.getPlatformFactory(PlatformFactory.java:42)
        在 com.sun.glass.ui.Application.run(Application.java:146)
        在 com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:291)
        在 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:293)
        在 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:163)
        在 com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:659)
        在 com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:679)
        在 com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
        在 java.base/java.lang.Thread.run(Thread.java:829)
加载Glass工厂类失败
主线程异常 java.lang.NullPointerException
        在 com.sun.glass.ui.Application.run(Application.java:146)
        在 com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:291)
        在 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:293)
        在 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:163)
        在 com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:659)
        在 com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:679)
        在 com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
        在 java.base/java.lang.Thread.run(Thread.java:829)

解决方案

核心问题是跨平台打包时未正确包含JavaFX的Native库,加上模块加载配置冲突,导致Linux/MacOS系统无法找到依赖的平台组件。

1. 清理重复依赖,用OpenJFX插件统一管理

你同时手动添加了各平台JavaFX依赖和使用OpenJFX插件,两者冲突导致打包时未正确引入对应平台的Native库。修改build.gradle:

  • 删除dependencies块内所有手动添加的javafx-*依赖,OpenJFX插件会自动根据目标平台引入对应版本的依赖
  • 同步javafx块内的版本号与之前使用的一致(如17.0.8)

修改后相关代码如下:

dependencies {
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0'
    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0'
}

javafx {
    version = '17.0.8'
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

2. 调整ShadowJar配置,打包Native库

JavaFX的GUI功能依赖平台特定的Native库,ShadowJar默认不会自动打包这些资源,需手动配置:

shadowJar {
    archiveBaseName = "duke"
    archiveClassifier = null
    
    // 将各平台的Native库打包到Jar内的native目录
    from(configurations.runtimeClasspath) {
        include '**/lib/**/*.so' // Linux平台
        include '**/lib/**/*.dylib' // MacOS平台
        include '**/lib/**/*.dll' // Windows平台
        into 'native'
    }
    
    // 配置Manifest,指定模块路径与主类
    manifest {
        attributes(
            'Main-Class': 'seedu.Launcher',
            'Module-Path': './native'
        )
    }
}

3. 修正模块加载配置

报错提示类被加载到未命名模块,需确保module-info.java配置正确:

module seedu {
    requires javafx.controls;
    requires javafx.fxml;
    
    // 若FXML文件在seedu包下,需开放权限给FXML框架访问
    opens seedu to javafx.fxml;
    exports seedu;
}

4. 跨平台打包更可靠方案:用jlink生成独立运行镜像

ShadowJar打包的FatJar在JavaFX跨场景下易出问题,更稳定的方式是用jlink生成包含JRE和所有依赖的独立运行镜像:
在build.gradle中添加jlink配置:

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'duke'
    }
}

执行./gradlew jlink后,build/image目录会生成对应平台的可执行文件,无需依赖系统JRE即可直接运行。

5. Linux系统额外依赖检查

若Linux系统仍报错,需检查是否安装GTK3依赖:

  • Ubuntu/Debian:sudo apt-get install libgtk-3-0
  • Fedora/RHEL:sudo dnf install gtk3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:27:06