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

解决Launch4j生成exe时JavaFX运行时组件缺失报错问题

问题

我是编程新手,正在给项目生成.exe文件。项目本身运行无报错或警告,已通过shadowJar插件生成fat-jar,修改IntelliJ的Run配置后可正常运行,配置参数如下:

--module-path
"C:\Program Files\Java\javafx-sdk-17.0.7\lib"
--add-modules
javafx.controls,javafx.fxml

用Launch4j生成.exe后无法运行,报错:JavaFX runtime components are missing, and are required to run this application。附上我的build.gradle文件:

plugins {
    id 'java'
    id 'application'
    id 'org.javamodularity.moduleplugin' version '1.8.12'
    id 'org.openjfx.javafxplugin' version '0.0.13'
    id 'com.github.johnrengelman.shadow' version '7.1.0'
}

group 'com.preventivoApp'
version '1.0-SNAPSHOT'
mainClassName = 'com.appproject_preventivo.QuoteMainApplication'

repositories {
    mavenCentral()
}
	ext {
    junitVersion = '5.9.1'
}

sourceCompatibility = '17'
targetCompatibility = '17'

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

application {
    mainModule = 'com.appproject_preventivo'
    mainClass = 'com.appproject_preventivo.QuoteMainApplication'
}

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

dependencies {
    implementation('org.controlsfx:controlsfx:11.1.2')

    implementation 'org.openjfx:javafx-fxml:20'
    implementation 'org.openjfx:javafx-controls:20'

    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")

    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.0'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.0'
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.15.0'

    implementation group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.28'
}

test {
    useJUnitPlatform()
}
shadowJar {
    zip64 true
    mergeServiceFiles()
    manifest {
        attributes 'Main-Class': 'com.appproject_preventivo.QuoteMainApplication'
    }
}
解决方案

1. 修正build.gradle中的依赖问题

首先统一JavaFX版本,避免依赖冲突,同时优化shadowJar配置以适配模块化:

plugins {
    id 'java'
    id 'application'
    id 'org.javamodularity.moduleplugin' version '1.8.12'
    id 'org.openjfx.javafxplugin' version '0.0.13'
    id 'com.github.johnrengelman.shadow' version '7.1.0'
}

group 'com.preventivoApp'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext {
    junitVersion = '5.9.1'
    javafxVersion = '17.0.7' // 和IntelliJ使用的JavaFX SDK版本一致
}

sourceCompatibility = '17'
targetCompatibility = '17'

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

application {
    mainModule = 'com.appproject_preventivo'
    mainClass = 'com.appproject_preventivo.QuoteMainApplication'
}

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

dependencies {
    implementation('org.controlsfx:controlsfx:11.1.2')

    // 移除重复的JavaFX依赖,javafx插件会自动引入对应版本的依赖
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")

    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.0'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.0'
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.15.0'

    implementation group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.28'
}

test {
    useJUnitPlatform()
}

shadowJar {
    zip64 true
    mergeServiceFiles()
    manifest {
        attributes 'Main-Class': 'com.appproject_preventivo.QuoteMainApplication'
        // 添加模块主类属性,适配模块化启动
        attributes 'Module-Main-Class': 'com.appproject_preventivo/com.appproject_preventivo.QuoteMainApplication'
    }
    // 确保打包所有运行时依赖,包括JavaFX
    from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}

修改后重新执行./gradlew shadowJar生成新的fat-jar。

2. 调整Launch4j配置传递JavaFX参数

打开Launch4j,在JVM Options中添加以下参数(替换成你本地JavaFX SDK的实际路径,或者用相对路径):

--module-path "C:\Program Files\Java\javafx-sdk-17.0.7\lib"
--add-modules javafx.controls,javafx.fxml

如果想让exe可移植,把JavaFX SDK的lib目录复制到exe同目录下,参数改为相对路径:

--module-path "./javafx/lib"
--add-modules javafx.controls,javafx.fxml

3. 备选方案:用jlink生成自定义JRE(推荐)

这种方式会把JavaFX和JRE打包在一起,不需要用户额外安装Java或JavaFX:

  1. 在build.gradle末尾添加jlink任务:
jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'QuoteApp'
    }
}
  1. 执行./gradlew jlink,生成的运行时环境在build/image目录下,里面包含自定义JRE和启动脚本。
  2. 在Launch4j中,设置Runtime的Bundled JRE path为build/image/jre,Main class填写com.appproject_preventivo.QuoteMainApplication,直接打包即可。
错误原因
  • Launch4j默认不会传递JavaFX所需的模块参数,必须手动添加--module-path和--add-modules。
  • build.gradle中JavaFX版本不一致(插件用17.0.2,依赖用20),导致依赖冲突,可能使fat-jar无法正确加载JavaFX组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:59:51