使用jpackage构建macOS的pkg安装包启动提示找不到主类如何解决
问题核心原因
当前Gradle配置存在任务冲突和类路径配置缺失两个问题,导致jpackage打包后的应用无法正确加载主类,具体修复步骤如下:
任务冲突说明
你同时配置了bootJar和jar两个任务作为jpackage的前置依赖,Spring Boot项目中默认两个任务的输出文件名一致,执行顺序靠后的jar任务会把bootJar生成的可执行jar覆盖为不含依赖、清单配置不符合jpackage要求的普通jar包,即使你能在jar包里找到主类文件,JVM也无法正常加载。两种修复方案可选:
方案1:使用Spring Boot可执行jar(推荐,配置更简单)
不需要单独拆分依赖,直接使用bootJar生成的全量可执行jar作为jpackage的输入,修改后的配置如下:
def os = org.gradle.internal.os.OperatingSystem.current() def pkgType = os.windows ? 'msi' : os.linux ? 'deb' : 'pkg' jpackage { dependsOn clean dependsOn bootJar type = pkgType // 直接指定bootJar的输出目录作为输入 input = tasks.bootJar.getDestinationDirectory().get().asFile.absolutePath destination = "$buildDir/dist" appName = 'Example' vendor = 'com.example' // 用bootJar的输出文件名作为主jar mainJar = tasks.bootJar.getArchiveFileName().get() mainClass = 'com.example.Application' javaOptions = ['-Dfile.encoding=UTF-8'] }
方案2:使用普通jar+外置依赖
如果需要保留外置依赖的拆分结构,需要补充类路径配置,同时移除对bootJar的依赖:
def os = org.gradle.internal.os.OperatingSystem.current() def pkgType = os.windows ? 'msi' : os.linux ? 'deb' : 'pkg' def inputDir = "$buildDir/input" task copyDependencies (type: Copy) { from configurations.runtimeClasspath into inputDir } task copyJar (type: Copy) { from tasks.jar into inputDir } jpackage { dependsOn clean dependsOn copyDependencies dependsOn copyJar type = pkgType input = inputDir destination = "$buildDir/dist" appName = 'Example' vendor = 'com.example' mainJar = tasks.jar.getArchiveFileName().get() mainClass = 'com.example.Application' // 补充类路径配置,加载input目录下所有jar包 classPath = './*' javaOptions = ['-Dfile.encoding=UTF-8'] }
- 验证方法
打包安装后右键应用选择「显示包内容」,打开Contents/app/Example.cfg(文件名和你的appName一致),确认以下配置正确:
app.mainclass的值为com.example.Applicationapp.classpath包含你的主jar和所有依赖jar
修改后重新打包即可解决主类找不到的问题。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

