使用Gradle将Java代码打包为Jar并生成Exe后遇JRE依赖问题
解决Java程序打包为独立EXE(无需依赖系统JRE)
问题根源
你现在的launch4j配置只是把Jar包套了个EXE启动壳,没把JRE打包进去,所以运行时会要求目标电脑装对应版本的JRE。要生成像C程序那样的独立EXE,必须把JRE和程序打包在一起。
方案一:用Launch4j打包完整本地JRE
直接修改你的build.gradle,在createExe任务里加JRE打包配置,让launch4j把本地JRE复制到EXE所在目录,启动时优先用本地JRE:
plugins { id 'java' id 'idea' id 'com.github.johnrengelman.shadow' version '7.1.2' id 'edu.sc.seis.launch4j' version '2.5.2' } jar.enabled = false group 'project' version '1.0-SNAPSHOT' java { sourceCompatibility = 1.8 } repositories { mavenCentral() // 必须加这个仓库,不然插件可能下不到依赖 } dependencies { } shadowJar { archiveBaseName.set('toJarToExeFat') archiveVersion.set('0.1') archiveClassifier.set('') manifest { attributes 'Main-Class': 'project.main' } } tasks.shadowJar.dependsOn tasks.build createExe { outfile = 'test.exe' mainClassName = 'project.main' jar = "${buildDir}/libs/toJarToExeFat-0.1.jar" // 用Gradle变量替代硬编码路径,更灵活 // JRE核心配置:打包本地JRE到程序目录 jre { path = 'C:/Program Files/Java/jdk1.8.0_301/jre' // 换成你自己的本地JRE路径,版本要和代码兼容 bundleJre = true // 开启JRE打包,会把JRE复制到EXE同目录 minVersion = '1.8.0' maxVersion = '1.8.0' jre64 = true // 如果你用的是64位JRE,就设为true,32位设为false } // 可选:给EXE加图标,把图标文件放在src/main/resources下就行 // icon = 'src/main/resources/app.ico' } tasks.createExe.dependsOn tasks.shadowJar
操作步骤
- 把
jre.path替换成你本地的JRE路径(比如你装的JDK下的jre文件夹) - 执行命令
./gradlew createExe(Windows下用gradlew.bat createExe) - 打包完成后,去
build/launch4j目录,里面有test.exe和jre文件夹,把整个目录复制到其他电脑就能直接运行,不用装JRE
方案二:用JLink构建精简JRE(更小体积)
如果觉得完整JRE太占空间,可以用JLink做个只包含程序必需模块的精简JRE,再打包:
修改后的build.gradle:
plugins { id 'java' id 'idea' id 'com.github.johnrengelman.shadow' version '7.1.2' id 'edu.sc.seis.launch4j' version '2.5.2' } jar.enabled = false group 'project' version '1.0-SNAPSHOT' java { sourceCompatibility = 1.8 targetCompatibility = 1.8 } repositories { mavenCentral() } dependencies { } // 任务:构建精简JRE task createRuntime(type: Exec) { def jdkPath = 'C:/Program Files/Java/jdk1.8.0_301' // 换成你的JDK路径,注意JDK8要u261及以上版本才支持jlink def outputDir = "${buildDir}/runtime" commandLine "${jdkPath}/bin/jlink.exe", '--module-path', "${jdkPath}/jmods", '--add-modules', 'java.base', // 你的程序只用到java.base模块,按需添加其他模块 '--output', outputDir, '--strip-debug', // 去掉调试信息,减小体积 '--compress', '2' // 开启压缩 } shadowJar { archiveBaseName.set('toJarToExeFat') archiveVersion.set('0.1') archiveClassifier.set('') manifest { attributes 'Main-Class': 'project.main' } } tasks.shadowJar.dependsOn tasks.build createExe { outfile = 'test.exe' mainClassName = 'project.main' jar = "${buildDir}/libs/toJarToExeFat-0.1.jar" // 指定用我们自己构建的精简JRE jre { path = "${buildDir}/runtime" minVersion = '1.8.0' maxVersion = '1.8.0' jre64 = true } } // 先构建精简JRE,再打包EXE tasks.createExe.dependsOn tasks.shadowJar, tasks.createRuntime
注意点
- JDK8的jlink需要版本在u261及以上,要是你JDK版本太低,要么升级JDK,要么用方案一
- 生成的
runtime文件夹比完整JRE小很多,适合分发
内容的提问来源于stack exchange,提问作者tochitopor
相关产品推荐
相关产品推荐

