解决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:
- 在build.gradle末尾添加jlink任务:
jlink { options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages'] launcher { name = 'QuoteApp' } }
- 执行
./gradlew jlink,生成的运行时环境在build/image目录下,里面包含自定义JRE和启动脚本。 - 在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
相关产品推荐
相关产品推荐

