深入Spring Boot:怎样排查 Cannot determine embedded database driver class for database type NONE
写在前面
这个demo来说明怎么一步步排查一个常见的spring boot AutoConfiguration的错误。
https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-database-type-NONE
调试排查 Cannot determine embedded database driver class for database type NONE 的错误
把工程导入IDE里,直接启动应用,抛出来的异常信息是:
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-11-29 14:26:34.478 ERROR 29736 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
其实这时有两个思路,直接google搜索Cannot determine embedded database driver class for database type NONE,就可以找到解决办法。
第二种方式,仔细查看日志内容,可以发现有To display the auto-configuration report re-run your application with 'debug' enabled.。
搜索下这个,就可以在spring的官方网站上找到相关的信息:https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html
就是用户只要配置了debug这个开关,就会把auto-configuration 相关的信息打印出来。
熟悉spring的环境变量注入的话,就可以知道有几种打开这个的方式:
- 在
args里增加--debug - 在application.properties里增加
debug=true - 通过
-Ddebug=true
增加debug开关之后的信息
增加debug开关之后,可以看到打印出了错误堆栈:
2017-11-29 14:33:08.776 DEBUG 29907 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : Application failed to start due to an exception
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:245) ~[spring-boot-autoconfigure-1.4.7.RELEASE.jar:1.4.7.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:182) ~[spring-boot-autoconfigure-1.4.7.RELEASE.jar:1.4.7.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:42) ~[spring-boot-autoconfigure-1.4.7.RELEASE.jar:1.4.7.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat.dataSource(DataSourceConfiguration.java:53) ~[spring-boot-autoconfigure-1.4.7.RELEASE.jar:1.4.7.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
抛出异常的代码是:
/**
* Determine the driver to use based on this configuration and the environment.
* @return the driver to use
* @since 1.4.0
*/
public String determineDriverClassName() {
if (StringUtils.hasText(this.driverClassName)) {
Assert.state(driverClassIsLoadable(),
"Cannot load driver class: " + this.driverClassName);
return this.driverClassName;
}
String driverClassName = null;
if (StringUtils.hasText(this.url)) {
driverClassName = DatabaseDriver.fromJdbcUrl(this.url).getDriverClassName();
}
if (!StringUtils.hasText(driverClassName)) {
driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
}
if (!StringUtils.hasText(driverClassName)) {
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
this.environment, "driver class");
}
return driverClassName;
}
可以看出来是没有找到 DataSource 的driver class,然后抛出了 DataSourceBeanCreationException。
那么一种解决办法是,在maven依赖里加入一些 DataSource driver class。
但是应用自己的代码里并没有使用DataSource,哪里导致spring boot要创建一个DataSource对象?
哪里导致spring boot要创建DataSource
从异常栈上,可以找到DataSourceConfiguration$Tomcat 这个类,那么查找下它的引用,可以发现它是被org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.PooledDataSourceConfiguration import引入的。
@Configuration
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,
DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,
DataSourceConfiguration.Generic.class })
protected static class PooledDataSourceConfiguration {
}
那么 PooledDataSourceConfiguration 是怎么生效的呢?从代码上可以看到@Conditional(PooledDataSourceCondition.class)。
那么再看PooledDataSourceCondition的具体实现:
/**
* {@link AnyNestedCondition} that checks that either {@code spring.datasource.type}
* is set or {@link PooledDataSourceAvailableCondition} applies.
*/
static class PooledDataSourceCondition extends AnyNestedCondition {
PooledDataSourceCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(prefix = "spring.datasource", name = "type")
static class ExplicitType {
}
@Conditional(PooledDataSourceAvailableCondition.class)
static class PooledDataSourceAvailable {
}
}
PooledDataSourceCondition引入了@Conditional(PooledDataSourceAvailableCondition.class) :
/**
* {@link Condition} to test if a supported connection pool is available.
*/
static class PooledDataSourceAvailableCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("PooledDataSource");
if (getDataSourceClassLoader(context) != null) {
return ConditionOutcome
.match(message.foundExactly("supported DataSource"));
}
return ConditionOutcome
.noMatch(message.didNotFind("supported DataSource").atAll());
}
/**
* Returns the class loader for the {@link DataSource} class. Used to ensure that
* the driver class can actually be loaded by the data source.
* @param context the condition context
* @return the class loader
*/
private ClassLoader getDataSourceClassLoader(ConditionContext context) {
Class<?> dataSourceClass = new DataSourceBuilder(context.getClassLoader())
.findType();
return (dataSourceClass == null ? null : dataSourceClass.getClassLoader());
}
}
从代码里,可以看到是尝试查找dataSourceClass,如果找到,条件就成立。那么debug下,可以发现查找到的dataSourceClass是:org.apache.tomcat.jdbc.pool.DataSource 。
那么再看下org.apache.tomcat.jdbc.pool.DataSource这个类是从哪里来的呢?
从maven依赖树可以看到,依赖是来自:spring-boot-starter-jdbc。所以是应用依赖了spring-boot-starter-jdbc,但是并没有配置DataSource引起的问题。
问题解决办法
有两种:
- 没有使用到
DataSource,则可以把spring-boot-starter-jdbc的依赖去掉,这样就不会触发spring boot相关的代码 - 把spring boot自动初始化
DataSource相关的代码禁止掉
禁止的办法有两种:
在main函数上配置exclude
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })在application.properties里配置:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
总结
- 应用没有使用到
DataSource,但是在pom.xml里引入了spring-boot-starter-jdbc spring-boot-starter-jdbc带入了tomcat-jdbc,它里面有org.apache.tomcat.jdbc.pool.DataSource- spring boot里的
PooledDataSourceConfiguration,判断classpath下面有DataSource的实现类,尝试去创建DataSourcebean - 在初始化
DataSourceProperties时,尝试通过jdbc的url来探测driver class - 因为应用并没有配置url,所以最终在
DataSourceProperties.determineDriverClassName()里抛出Cannot determine embedded database driver class for database type NONE
最后:
- 排查spring boot的AutoConfiguration问题时,可以按异常栈,一层层排查
Configuration是怎么引入的,再排查Condition具体的判断代码。
深入Spring Boot:怎样排查 Cannot determine embedded database driver class for database type NONE的更多相关文章
- 【spring cloud】【spring boot】项目启动报错:Cannot determine embedded database driver class for database type NONE
解决参考文章:https://blog.csdn.net/hengyunabc/article/details/78762097 spring boot启动报错如下: Error starting A ...
- Spring boot出现Cannot determine embedded database driver class for database type NONE
在spring boot项目中,我们在pom.xml文件中添加了mysql和mybatis的依赖,我们常常遇到下面这样的问题: Description: Cannot determine embedd ...
- Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embe
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationEx ...
- spriing boot 启动报错:Cannot determine embedded database driver class for database type NONE
最近在学习使用spring boot.使用maven创建好工程,只引用需要用到的spring boot相关的jar包,除此之外没有任何的配置. 写了一个最简单的例子,如下所示: package com ...
- 解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE
问题 如下: 2017-07-16 08:50:57.436 INFO 13524 --- [ main] c.p.p.web.PointshopWebApplication ...
- 解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)
问题 如下: 2017-07-16 08:50:57.436 INFO 13524 --- [ main] c.p.p.web.PointshopWebApplication ...
- Eureka 客户端启动报错误 Cannot determine embedded database driver class for database type NONE
用这种数据库配置就是死活连不上数据库 提示:Cannot determine embedded database driver class for database type NONE 解决方式: 启 ...
- Springboot项目启动报错,提示Cannot determine embedded database driver class for database type NONE
我在springboot项目里面引入了数据库的配置: <dependency> <groupId>org.mybatis.spring.boot</groupId> ...
- SpringBoot项目报错Cannot determine embedded database driver class for database type NONE
原因: Cannot determine embedded database driver class for database type NONE 这是因为spring boot默认会加载org.s ...
随机推荐
- secureCRT关闭连接自动关闭tomcat服务
下午遇到一个神奇的问题: secureCRT登陆某个服务器,用shell脚本启动./catalina.sh start,打开日志tail -f catalina.out,此时 手动关闭连接窗口,导致t ...
- Spark任务提交jar包依赖解决方案
转载自:http://blog.csdn.net/wzq294328238/article/details/48054525 通常我们将Spark任务编写后打包成 ...
- Spring Cloud(Dalston.SR5)--Eureka 服务提供者
要使微服务应用向注册中心发布自己,首先需要在 pom.xml 配置文件中增加对 spring-boot-starter-eureka 的依赖,然后在主类中增加 @EnableDiscoveryClie ...
- AXI_LITE源码学习笔记
AXI_LITE源码学习笔记 1. axi_awready信号的产生 准备接收写地址信号 // Implement axi_awready generation // axi_awready is a ...
- 一文说尽 MySQL 优化原理
说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原 ...
- C++Builder 网站。记住学习
http://www.ccrun.com/ C++Builder
- ubuntu-docker入门到放弃(二)docker初探(基本用法及命令)
一.使用公共镜像 docker有一个开源的镜像管理系统,上面有很多常见的images,如mysql,nginx,tomcat等,可以直接根据自己的需求下载下来用,还有系统images,如redhat, ...
- dubbo-admin在jdk8下不兼容
参考这里 修改pom.xml webx的依赖改为3..6版 <dependency> <groupId>com.alibaba.citrus</groupId> & ...
- 【Git】Git使用--常用命令
查看所有分支 git branch -a 查看本地分支 git branch 切换分支 git checkout test demo git checkout release_1.3.1 (切换到re ...
- final与abstract关键字
final特点: 1:这个关键字是一个修饰符,可以修饰类,方法,变量. 2:被final修饰的类是一个最终类,不可以被继承. 3:被final修饰的方法是一个最终方法,不可以被覆盖. 4:被final ...