jjzjj

Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the

zev1n 2023-07-11 原文

一、问题

在启动springboot项目中遇到如下问题:

Description:
Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class

Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

这个问题其实是url和数据源配置错误问题,果断查看配置文件和依赖。

另外,本项目用的是mybatisPlus+MySQL,使用默认连接池hakis

———————————————————————————————

二、原代码展示

1、配置文件

server:
  port: 9999
spring:
  redis:
    host: 127.0.0.1
    port: 6379
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lkd_user?characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: root
经过校对,没有问题

2、依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <groupId>com.zb</groupId>
    <artifactId>mysec</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--fastjson依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.33</version>
        </dependency>
        <!--jwt依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>
经过校对,暂时没有发现错误

———————————————————————————————

三、发现

发现没有存在明显的配置文件和依赖的问题,于是又看了下控制台打印日志,真正错误其实在上面,日志级别为warn。

2022-08-21 19:10:31.248 WARN 39656 — [ main] ConfigServletWebServerApplicationContext :
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userDetailServiceImpl’: Unsatisfied dependency expressed through field ‘tbUserMapper’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tbUserMapper’ defined in file [D:\maven\spring\springcloud\mysec\target\classes\com\zb\mapper\TbUserMapper.class]: Unsatisfied dependency expressed through bean property ‘sqlSessionFactory’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘sqlSessionFactory’ defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Unsatisfied dependency expressed through method ‘sqlSessionFactory’ parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dataSource’ defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration H i k a r i . c l a s s ] : B e a n i n s t a n t i a t i o n v i a f a c t o r y m e t h o d f a i l e d ; n e s t e d e x c e p t i o n i s o r g . s p r i n g f r a m e w o r k . b e a n s . B e a n I n s t a n t i a t i o n E x c e p t i o n : F a i l e d t o i n s t a n t i a t e [ c o m . z a x x e r . h i k a r i . H i k a r i D a t a S o u r c e ] : F a c t o r y m e t h o d ′ d a t a S o u r c e ′ t h r e w e x c e p t i o n ; n e s t e d e x c e p t i o n i s o r g . s p r i n g f r a m e w o r k . b o o t . a u t o c o n f i g u r e . j d b c . D a t a S o u r c e P r o p e r t i e s Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties Hikari.class]:Beaninstantiationviafactorymethodfailed;nestedexceptionisorg.springframework.beans.BeanInstantiationException:Failedtoinstantiate[com.zaxxer.hikari.HikariDataSource]:FactorymethoddataSourcethrewexception;nestedexceptionisorg.springframework.boot.autoconfigure.jdbc.DataSourcePropertiesDataSourceBeanCreationException: Failed to determine a suitable driver class

这里打印了bean的依赖问题,如下:

userDetailServiceImpl——依赖——》tbUserMapperl——依赖——》 sqlSessionFactory——依赖——》MybatisPlusAutoConfiguration ——依赖——》dataSource——依赖——》jdbc.DataSourceProperties

这里最终原因是:Failed to determine a suitable driver class,翻译下就是:无法确定合适的驱动程序类。错误主要跟DataSource有关。

———————————————————————————————

四、找原因

1、查看DataSourceConfiguration类,看看导入的实际DataSource配置。

abstract class DataSourceConfiguration {
	//创建DataBase
	@SuppressWarnings("unchecked")
	protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
		return (T) properties.initializeDataSourceBuilder().type(type).build();
	}
	
	/**
	 * Hikari DataSource configuration.
	 */
	@Configuration
	@ConditionalOnClass(HikariDataSource.class)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
			matchIfMissing = true)
	static class Hikari {

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.hikari")
		public HikariDataSource dataSource(DataSourceProperties properties) {
			HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
			if (StringUtils.hasText(properties.getName())) {
				dataSource.setPoolName(properties.getName());
			}
			return dataSource;
		}
	//省略其他Database配置(tomcat 、dbcp2、generic)
	}
}

这里断点,走的是HikariDataSource的dataSource()工厂方法,然后调用createDataSource()。

评估表达式(ALT+F8)计算createDataSource(),正好是导致异常的最终原因:

org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

(断点的时候已经发现jdbc爆红,没有成功导入)

继续往下走,进入到DataSourceProperties类initializeDataSourceBuilder()

public DataSourceBuilder<?> initializeDataSourceBuilder() {
	return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName())
			.url(determineUrl()).username(determineUsername()).password(determinePassword());
}

这里采用建造者模式链式调用,方法依次为创建——》类型——》驱动类名——》URL——》用户名——》密码。

评估表达式(ALT+F8)递进式计算:链式调用的返回结果。发现链式调用到driverClassName(determineDriverClassName())报错,并且后面也的determine()全部报错。

(这里已经发现问题,猜测配置文件声明的DriverClassName、url、username、password没有被识别到)

继续往下走,进入到determineDriverClassName()方法

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)) {
			//这里正好是控制台日志warn信息的最后一行提示
			throw new DataSourceBeanCreationException("Failed to determine a suitable driver class", this,
					this.embeddedDatabaseConnection);
		}
		return driverClassName;
	}

运行到这已经结束,错误信息中嵌套的最后异常就是出自这里

DataSourceBeanCreationException: Failed to determine a suitable driver class

断点中发现,该方法的类DataSourceProperties中的字段driverClassName、url、username、password全部为NULL。

于是又打开了其他运行正常的项目,断点上述各个位置,重新debug

首先进入到DataSourceConfiguration类的dataSource方法

可以看到,这个时候已经完成配置项的读取,往下走到DataSourceProperties类的initializeDataSourceBuilder()方法

这里并没有引发异常,同时发现determineXXX()方法都能得到对应的值。

到这,可以确定是配置信息没有成功被读取到,也就是YAML配置失效。

———————————————————————————————

五、解决方案

1、检查YAML文件位置、是否存在语法错误(四个配置项都没有成功读取,可以排除)

2、查看POM文件是否存在配置错误

最后发现问题是POM打包方式错误,多写了一行

    <modelVersion>4.0.0</modelVersion>
<!--    <packaging>pom</packaging>-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

———————————————————————————————

六、建议

1、不用看mybatis的mapper接口和映射文件、实体类。

项目启动时没有查数据库,也就没有调用mapper层,自然不会引发这个错误。
就算报错上提示信息也很明确,网上很多说要检查这个,感觉没有必要。

2、看yml/properties配置文件中跟url相关的,是否存在错误。

配置写多了,基本不会出现语法或声明错误,而且有代码提示

3、多断点调试,没必要重复性检查代码是否写错,结果半天也找不出来。

有关Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the的更多相关文章

  1. H2数据库配置及相关使用方式一站式介绍(极为详细并整理官方文档) - 2

    目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式

  2. ruby - 如何为 WordPress 多站点编写 h2o webserver mruby 处理程序? - 2

    这就是Apache所需要的。我想知道howIdothisinh2o.RewriteEngineOnRewriteBase/RewriteRule^index\.php$-[L]#addatrailingslashto/wp-adminRewriteRule^([_0-9a-zA-Z-]+/)?wp-admin$$1wp-admin/[R=301,L]RewriteCond%{REQUEST_FILENAME}-f[OR]RewriteCond%{REQUEST_FILENAME}-dRewriteRule^-[L]RewriteRule^([_0-9a-zA-Z-]+/)?(wp-(c

  3. javascript - 从 ajax jquery post 响应中获取 <h2> 元素内的文本 - 2

    有什么方法可以获取元素内的文本,该元素是来自ajaxjquery加载的响应。我需要从ajax页面获取响应文本中存在的元素内的文本。以下是我的ajax代码:varurl='...';varsaveData=$.ajax({type:'POST',url:url,data:{data:data},dataType:"text",success:function(resultData){callback(resultData);//needtogetthetexthere..}});saveData.error(function(){console.log("RequesttoAPInots

  4. Javascript: execCommand ("removeformat") 不去除 h2 标签 - 2

    我正在调整一个所见即所得的编辑器,我正在尝试创建一个图标,它将去除h2的选定文本。在以前的版本中,以下命令运行良好:oRTE.document.execCommand("removeformat",false,"");但在当前版本中,尽管该命令成功地从所选文本中删除了粗体、下划线、斜体等标记,但它仍保留了h2标记。(有趣的是,execCommand("formatblock"...)成功创建了h2标签。)我在想我将不得不放弃execCommand并找到另一种方法,但我也在想这不仅仅是一行代码!将不胜感激。 最佳答案 您可以将格式更改

  5. Windows 中的 Python h2o : cannot initialize (TypeError: argument of type 'NoneType' is not iterable) - 2

    我正在尝试在我的公司使用pythonh2o。使用命令后:>importh2o>h2o.init()我得到了h2o\connection.py:110:UserWarning:Proxyenvironmentvariable`HTTP_PROXY`withvalue`http://username:password@proxy.**.com:8080`found.ThismayinterferewithyourH2OConnection.warnings.warn("Proxyenvironmentvariable`"+name+"`withvalue`"+value+"`found.T

  6. r - Windows 上的 H2O XGBoost : Error: java. lang.UnsatisfiedLinkError : ml. dmlc.xgboost4j.java.XGBoostJNI.XGDMatrixCreateFromCSREx([J[I[FI[J]I - 2

    当我尝试使用H2O3.12.01通过h2o.xgboost()在Windows7和WindowsServer2008R2上的R中运行XGboost时,我收到以下错误:Error:java.lang.UnsatisfiedLinkError:ml.dmlc.xgboost4j.java.XGBoostJNI.XGDMatrixCreateFromCSREx([J[I[FI[J)I这是一个可重现的例子:library(h2o)h2o.init(nthreads=-1)h2o.no_progress()#Don'tshowprogressbarsinRMarkdownoutput#Impor

  7. javascript - 我怎样才能使 jQuery 直接转到 <h2 id ="id-name">? - 2

    我想让jQuery直接(不需要动画)导航到我传入变量的id。我有各种标记,例如id="content",id="edit",id="..."那是标题。使用PHP进行验证时,我将输出一个类似varNAVIGATE_TO=的变量我想把网站移到那个id位置。就像我做的那样domain.tld/page#edit或#content但是使用jQuery是因为当我加载页面时,我的PHP框架不允许我指示哈希值。 最佳答案 你可以设置location.hash到id你需要浏览器滚动到:window.location.hash='#edit';

  8. php - 使用 PHP 解析 HTML 并在下一个 h2 之前的 h2 之后获取所有 h3 - 2

    我正在寻找文章中的第一个h2。找到后,查找所有h3,直到找到下一个h2。冲洗并重复,直到找到所有标题和副标题。在您立即将此问题标记或关闭为重复解析问题之前,请注意问题标题,因为这与基本节点检索无关。我已经把那部分记下来了。我正在使用DOMDocument使用DOMDocument::loadHTML()解析HTML,DOMDocument::getElementsByTagName()和DOMDocument::saveHTML()检索文章的重要标题。我的代码如下:$matches=array();$dom=newDOMDocument;$dom->loadHTML($content)

  9. php - 用 TCPDF 定位 h1,h2,h3 和其他标签 - 2

    我正在尝试使用HTML代码使用TCPDF制作PDF文档。目前我使用这段代码://setfont$pdf->SetFont('dejavusans','',36);//addapage$pdf->AddPage();$html='.h1{color:#2B6999;font-weight:normal;}Test';//outputtheHTMLcontent$pdf->writeHTML($html,true,false,true,false,'C');我怎样才能定位这个文本?我不能在标签margin-top等之间使用。谁能帮我解决这个问题? 最佳答案

  10. php - 在帖子内容的第一个 h2 标签之前插入广告 - 2

    我想在帖子的第一个h2标签之前插入广告。我试过的代码在下面,但是广告出现在内容之后而不是之前。我希望在内容之前而不是之后插入广告。/*Insertadsaftersecondparagraphofsinglepostcontent.*/add_filter('the_content','prefix_insert_post_ads');functionprefix_insert_post_ads($content){$ad_code='Thisismyads';if(is_single()&&!is_admin()){returnprefix_insert_after_paragrap

随机推荐