现象:修改druid配置,启动application类,程序无法启动一直加载中,无法注册到Eureka。
mysql版本:8.0.15
配置:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
依赖:
com.alibaba:druid:1.1.10
compile files('lib/mysql-connector-java-8.0.15.jar')
runtime('mysql:mysql-connector-java')
最终问题入口:
com.alibaba.druid.util.MySqlUtils#getLastPacketReceivedTimeMs
正式开始调试,第一步代码 setTestOnBorrow(true):
@Bean
@Primary
@Qualifier("dataSource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));// 用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));// 密码
dataSource.setInitialSize(1);
dataSource.setMaxActive(20);
dataSource.setMinIdle(5);
dataSource.setMaxWait(30000);
dataSource.setValidationQuery("select user()");
dataSource.setTestOnBorrow(true);
dataSource.setTestWhileIdle(true);
dataSource.setPoolPreparedStatements(false);
return dataSource;
}
入口:
com.alibaba.druid.pool.DruidDataSource#getConnection(long)
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
return getConnectionDirect(maxWaitMillis);
}
}
代码入口getConnectionDirect(maxWaitMillis)
跟进去这段一段代码 testConnectionInternal(poolableConnection.holder, poolableConnection.conn)
if (testOnBorrow) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
}
继续找下去 MySqlUtils.getLastPacketReceivedTimeMs(conn)
if (valid && isMySql) {
long lastPacketReceivedTimeMs = MySqlUtils.getLastPacketReceivedTimeMs(conn);
if (lastPacketReceivedTimeMs > 0) {
long mysqlIdleMillis = currentTimeMillis - lastPacketReceivedTimeMs;
if (lastPacketReceivedTimeMs > 0 ... ...
}
}
问题就出现在这:Utils.loadClass("com.mysql.jdbc.MySQLConnection");
if (class_connectionImpl == null && !class_connectionImpl_Error) {
try {
class_connectionImpl = Utils.loadClass("com.mysql.jdbc.MySQLConnection");
} catch (Throwable error) {
class_connectionImpl_Error = true;
}
}
也就是说当前1.1.10不支持新的数据库驱动,
导致下面的代码Object connImpl = conn.unwrap(class_connectionImpl);由于驱动版本不一致解包失败
报错:"java.sql.SQLException: Unable to unwrap to interface com.mysal.jdbc.MySQLConnection'
升级druid到1.1.24后发现代码还是报错
此时1.1.24源码已经更新为:
if (class_connectionImpl == null && !class_connectionImpl_Error) {
try {
class_connectionImpl = Utils.loadClass("com.mysql.jdbc.MySQLConnection");
if (class_connectionImpl == null) {
class_connectionImpl = Utils.loadClass("com.mysql.cj.MysqlConnection");
if (class_connectionImpl != null) {
mysqlJdbcVersion6 = true;
}
}
} catch (Throwable error) {
class_connectionImpl_Error = true;
}
}
调试发现class_connectionImpl = Utils.loadClass("com.mysql.jdbc.MySQLConnection");不为空
排查依赖项发现:runtime('mysql:mysql-connector-java')
这个配置导致因为没有指定具体的版本号导致项目默认依赖了mysql-connector-java:5.1.40。
注释后解决,代码走正常想要用的驱动:
标签:TestOnBorrow,com,connectionImpl,druid,dataSource,mysql,true,class From: https://www.cnblogs.com/tomoto/p/17711848.htmlclass_connectionImpl = Utils.loadClass("com.mysql.cj.MysqlConnection");