如何用Gradle基于master.jar生成可执行Jar?主类找不到问题排查
Gradle打包可执行Jar问题修复与CI/CD方案
问题根源
- 源码路径配置错误:你把
sourceSets.main.java.srcDirs指向了具体类的目录,Gradle无法正确扫描并编译所有Java源码,导致生成的Jar仅包含空目录结构,没有编译后的class文件,所以体积极小且找不到主类。 - Class-Path语法错误:原配置中
configurations.runtimeClasspath { it.getName() }写法无效,无法生成正确的依赖类路径。 - 依赖未正确处理:原
jar任务未打包依赖的master.jar,或依赖路径配置错误。
修复方案
方案1:生成包含所有依赖的Fat Jar(推荐用于CI/CD)
这种方式会把自身代码和所有依赖打包到一个Jar里,无需额外携带libs目录,直接运行即可:
apply plugin: 'java' apply plugin: 'application' // 指定主类 mainClassName = 'com.robin.roh.QuickRouteJobScheduler' // 配置源码根目录,Gradle会自动识别包结构 sourceSets.main.java.srcDirs = ['src'] dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) } jar { // 将所有依赖的class文件和资源打包进Jar from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } manifest { attributes 'Main-Class': 'com.robin.roh.QuickRouteJobScheduler' } // 排除重复的META-INF文件,避免构建冲突 duplicatesStrategy = DuplicatesStrategy.EXCLUDE }
方案2:分离自身代码与依赖(适合需单独管理依赖的场景)
生成仅包含自身代码的Jar,同时在Manifest中配置依赖路径,运行时需保证libs目录与Jar同目录:
apply plugin: 'java' apply plugin: 'application' mainClassName = 'com.robin.roh.QuickRouteJobScheduler' sourceSets.main.java.srcDirs = ['src'] dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) } jar { manifest { attributes 'Main-Class': 'com.robin.roh.QuickRouteJobScheduler' // 正确生成依赖类路径,指向同目录下的libs文件夹 attributes 'Class-Path': configurations.runtimeClasspath.files.collect { "libs/${it.name}" }.join(' ') } } // 可选:自动将libs复制到构建输出目录,方便打包部署 task copyLibs(type: Copy) { from configurations.runtimeClasspath into "${buildDir}/libs/libs" } build.dependsOn copyLibs
操作步骤
- 替换原
build.gradle为上述任一配置(推荐方案1) - 执行构建命令:
./gradlew clean build - 生成的Jar位于
build/libs/目录下,运行命令:java -jar build/libs/QuickRouteJobScheduler.jar
BitBucket CI/CD配置
在项目根目录创建bitbucket-pipelines.yml,添加以下内容实现自动构建:
pipelines: default: - step: name: Build executable Jar image: gradle:jdk11 script: - gradle clean build artifacts: - build/libs/*.jar
流水线运行后,可在artifacts中下载生成的可执行Jar。
内容的提问来源于stack exchange,提问作者Robin William
相关产品推荐
相关产品推荐

