Docker部署Spring Web应用时出现数据源驱动类找不到问题
问题描述
我有一个基于PostgreSQL的Spring Web应用,在IntelliJ中运行正常,但打包成Docker镜像运行时出现数据源错误,日志如下:
00:59:44.724 [main] INFO com.example.fcs.FeedbackCollectionSystemApplication -- Starting FeedbackCollectionSystemApplication v2.15.3 using Java 19 with PID 1 (/FeedbackCollectionSystem.jar started by root in /) 00:59:44.728 [main] INFO com.example.fcs.FeedbackCollectionSystemApplication -- No active profile set, falling back to 1 default profile: "default" 00:59:45.799 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate -- Bootstrapping Spring Data JPA repositories in DEFAULT mode. 00:59:45.908 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate -- Finished Spring Data repository scanning in 96 ms. Found 2 JPA repository interfaces. 00:59:46.377 [main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext -- Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class 00:59:46.382 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:802) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:241) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1193) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:413) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1166) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1173) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:936) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1342) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1331) at com.example.fcs.FeedbackCollectionSystemApplication.main(FeedbackCollectionSystemApplication.java:10) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:643) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1166) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1441) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1348) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ... 27 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:178) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ... 41 common frames omitted Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class 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.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) at java.base/java.lang.reflect.Method.invoke(Method.java:578) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ... 42 common frames omitted
当前配置:
- application.properties:
spring.datasource.url=jdbc:"totaly correct url" spring.datasource.username="totaly correct username" spring.datasource.password="totaly correct password" spring.datasource.driver-class-name=org.postgresql.Driver
- build.gradle:
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.postgresql:postgresql:42.2.27' runtimeOnly 'org.postgresql:postgresql' testImplementation 'org.springframework.boot:spring-boot-starter-test' } bootJar { duplicatesStrategy = 'exclude' mainClass = 'com.example.fcs.FeedbackCollectionSystemApplication' } apply plugin: 'java' jar { manifest { attributes 'Main-Class': 'com.example.fcs.FeedbackCollectionSystemApplication' } }
另外,数据库已确认运行正常,且build.gradle中两次配置Main-Class,但jar包的MANIFEST.INF中未自动生成该属性,需手动添加。
解决方案
一、数据源驱动类识别失败问题
1. 修正application.properties配置
配置中URL、用户名、密码的引号是多余的,Spring Boot读取时会把引号当作值的一部分,导致URL格式错误,进而无法识别驱动类。修改为:
spring.datasource.url=jdbc:postgresql://your-db-host:port/db-name spring.datasource.username=your-username spring.datasource.password=your-password spring.datasource.driver-class-name=org.postgresql.Driver
2. 调整PostgreSQL依赖配置
同时声明implementation和runtimeOnly的PostgreSQL依赖可能导致冲突或打包时驱动类未被正确包含。保留其中一种即可,推荐使用runtimeOnly(驱动类仅在运行时需要):
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'org.postgresql:postgresql:42.2.27' // 指定版本避免兼容问题 testImplementation 'org.springframework.boot:spring-boot-starter-test' }
3. 确保Docker镜像使用可执行jar
Spring Boot的bootJar任务生成的是包含所有依赖的可执行jar,普通jar任务生成的jar不包含依赖。检查Dockerfile是否正确使用bootJar产物:
FROM openjdk:19-jdk-slim COPY build/libs/FeedbackCollectionSystem.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]
二、MANIFEST.INF不自动生成Main-Class问题
1. 移除冗余配置
Spring Boot项目应使用bootJar生成可执行jar,普通jar任务的配置属于冗余,删除后保留bootJar配置:
plugins { id 'java' id 'org.springframework.boot' version '2.15.3' // 确保Spring Boot插件已应用 id 'io.spring.dependency-management' version '1.1.3' } group = 'com.example' version = '2.15.3' sourceCompatibility = '19' dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'org.postgresql:postgresql:42.2.27' testImplementation 'org.springframework.boot:spring-boot-starter-test' } bootJar { duplicatesStrategy = 'exclude' mainClass = 'com.example.fcs.FeedbackCollectionSystemApplication' } test { useJUnitPlatform() }
2. 确保Spring Boot插件正确应用
Spring Boot插件会自动配置bootJar任务,必须在plugins块中声明该插件,否则无法自动生成MANIFEST属性。
3. 重新构建jar
执行命令./gradlew clean bootJar重新生成可执行jar,此时MANIFEST.INF会自动包含Main-Class属性。
内容的提问来源于stack exchange,提问作者Marat
相关产品推荐
相关产品推荐

