从MariaDB获取连接时遇认证协议不兼容及异常问题求助
咱们拆解你遇到的两个问题,一步步来解决:
一、客户端不支持服务器请求的认证协议
这个是连接失败的核心原因,通常是因为你的MariaDB JDBC客户端驱动版本太老,不兼容服务器端启用的新认证插件(比如MariaDB 10.4+默认使用的caching_sha2_password或ed25519)。
解决方法:
升级JDBC驱动(推荐方案)
替换成最新版的mariadb-java-client驱动。如果用Maven管理依赖,直接更新pom.xml里的依赖:<dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>3.3.3</version> <!-- 替换成当前最新版本 --> </dependency>如果是手动管理jar包,直接下载最新驱动包替换项目里的旧版本即可。
临时调整服务器认证插件(仅用于测试或过渡)
如果暂时没法升级驱动,可以修改MariaDB的配置文件(Linux是/etc/my.cnf或/etc/mysql/my.cnf,Windows是my.ini),添加以下配置:[mysqld] default-authentication-plugin=mysql_native_password重启MariaDB服务后,还需要重置你的数据库用户密码,指定使用旧认证插件:
ALTER USER '你的用户名'@'你的主机地址' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;注意:这个方法会降低安全性,不建议在生产环境长期使用。
二、线程中的IllegalMonitorStateException
这个异常是因为在ConnectionPoolImpl.run()方法的第128行,调用notifyAll()的线程没有持有该对象的锁。Java里明确规定:只有持有对象锁的线程,才能调用wait()/notify()/notifyAll()方法。
解决方法:
检查你的连接池代码,确保调用notifyAll()之前,已经通过synchronized块获取了对应的锁对象。比如:
// 假设锁对象是当前连接池实例 synchronized (this) { // 执行需要同步的逻辑,比如连接池状态更新 this.notifyAll(); // 现在调用就不会抛出异常了 }
确认你的代码里,notifyAll()是在synchronized代码块内部调用的,且锁对象和调用notifyAll()的对象一致。
内容的提问来源于stack exchange,提问作者Rohitesh




