Spring Boot可执行Fat Jar运行失败问题求助
问题
我用IntelliJ IDEA创建了一个全新的Spring Boot项目,引入了JPA和mysql-connector依赖。
build.gradle.kts 文件内容如下:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "3.1.1" id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.8.22" kotlin("plugin.spring") version "1.8.22" kotlin("plugin.jpa") version "1.8.22" } group = "com.example" version = "0.0.1-SNAPSHOT" java { sourceCompatibility = JavaVersion.VERSION_17 } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-web") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") runtimeOnly("com.mysql:mysql-connector-j") testImplementation("org.springframework.boot:spring-boot-starter-test") } tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs += "-Xjsr305=strict" jvmTarget = "17" } } tasks.withType<Test> { useJUnitPlatform() } tasks.withType<Jar> { duplicatesStrategy = DuplicatesStrategy.INCLUDE manifest { attributes["Main-Class"] = "com.example.test.TestApplicationKt" } from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) }
application.properties 文件内容如下:
spring.datasource.url=jdbc:mysql://localhost:3306/bizzle_db spring.datasource.username=root spring.datasource.password=1234 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
问题详情
我需要生成Fat Jar部署到Linux服务器,执行了以下步骤:
- 用
./gradlew jar命令生成Jar文件 - 用
java -jar file.jar命令运行Jar包
但运行时出现如下错误,而项目在IntelliJ IDEA中可以正常运行:
11:37:51.608 [main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext -- 上下文初始化期间遇到异常 - 取消刷新尝试: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration' 的Bean失败: 通过构造器参数0表达的依赖不满足: 创建名为 'dataSource' 的Bean失败,该Bean定义在类路径资源 [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] 中: 无法实例化 [com.zaxxer.hikari.HikariDataSource]: 工厂方法 'dataSource' 抛出异常,消息: 无法确定合适的驱动类 11:37:51.610 [main] ERROR org.springframework.boot.SpringApplication -- 应用运行失败 org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration' 的Bean失败: 通过构造器参数0表达的依赖不满足: 创建名为 'dataSource' 的Bean失败,该Bean定义在类路径资源 [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] 中: 无法实例化 [com.zaxxer.hikari.HikariDataSource]: 工厂方法 'dataSource' 抛出异常,消息: 无法确定合适的驱动类 at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:417) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:931) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) at com.example.test.TestApplicationKt.main(TestApplication.kt:13) Caused by: org.springframework.beans.factory.BeanCreationException: 创建名为 'dataSource' 的Bean失败,该Bean定义在类路径资源 [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] 中: 无法实例化 [com.zaxxer.hikari.HikariDataSource]: 工厂方法 'dataSource' 抛出异常,消息: 无法确定合适的驱动类 at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:659) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:647) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 27 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: 无法实例化 [com.zaxxer.hikari.HikariDataSource]: 工厂方法 'dataSource' 抛出异常,消息: 无法确定合适的驱动类 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) ... 41 common frames omitted Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: 无法确定合适的驱动类 at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:186) at org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails.getDriverClassName(PropertiesJdbcConnectionDetails.java:49) at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:55) at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:117) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ... 42 common frames omitted
解决方案
核心原因
你自定义的Jar任务没有适配Spring Boot的依赖打包逻辑,且使用了错误的打包命令:./gradlew jar生成的是普通Jar,不会自动包含runtimeOnly类型的依赖(比如MySQL驱动);而IDEA运行时会自动将所有runtime依赖加入类路径,所以本地运行正常,打包后运行找不到驱动类。
正确做法:使用Spring Boot官方的bootJar任务
Spring Boot Gradle插件已经内置了生成可执行Fat Jar的bootJar任务,无需自定义Jar任务,步骤如下:
- 删除
build.gradle.kts中自定义的tasks.withType<Jar>代码块 - 执行打包命令:
./gradlew bootJar - 生成的可执行Jar在
build/libs目录下,文件名格式为{项目名}-{版本号}.jar - 运行Jar:
java -jar build/libs/你的Jar文件名.jar
为什么这个方法有效
bootJar任务会自动处理所有依赖的打包(包括runtimeOnly的MySQL驱动),同时正确配置主类、依赖加载逻辑等,完全满足Spring Boot项目的Fat Jar部署需求。
内容的提问来源于stack exchange,提问作者Ali Asjad
相关产品推荐
相关产品推荐

