我正在尝试在 Scala 2.12 项目中从使用 MySQL Connector/J 转换为 MariaDB Connector/J 2.7.12。在思考 MariaDB 驱动程序存在错误一周后,我发现真正的问题是 sbt-assemble 的合并逻辑正在交换库,导致 MariaDB 驱动程序在连接到 MySQL 8 时抛出错误。
有问题的错误是:
java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=192.168.240.7)(port=3306)(type=master) : Client does not support authentication protocol requested by server. plugin type was = 'caching_sha2_password'
at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:73)
我知道这不是驱动程序,因为我在一个小型测试应用程序中使用了相同的驱动程序、Scala 和 Java。一旦我摆脱了
build.sbt
文件中的合并逻辑并手动排除重复项,效果就很好。不幸的是,实际的应用程序使用了更多的库。
有没有办法确保 sbt-assemble 首先从 MariaDB Connector/J jar 中选择类?如果没有,有人有包含该驱动程序的
build.sbt
文件吗?
尝试过:
mysql_native_password
auth 插件时连接到 MySQL 8。期待:用 MariaDB 驱动程序无缝替换 MySQL 驱动程序。
编辑:这是可以运行的示例应用程序。要打破它,请删除
excludeDependencies
部分并将其替换为标准合并逻辑。
玛丽亚.scala
package com.test
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException
import org.mariadb.jdbc.Driver
object Maria {
def main(args: Array[String]) = {
var connection:Connection = null
try {
println("Start...")
// DriverManager.registerDriver(new org.mariadb.jdbc.Driver())
Class.forName("org.mariadb.jdbc.Driver")
println("Registered driver")
connection = DriverManager.getConnection(
"jdbc:mariadb://maria-mysql2-1:3306/test?allowPublicKeyRetrieval=true",
"root", "password")
println(s"Connection valid: ${connection.isValid(5)}")
val statement = connection.createStatement()
val resultSet = statement.executeQuery("SELECT id, name FROM test")
while ( resultSet.next() ) {
val id = resultSet.getInt("id")
val name = resultSet.getString("name")
println(s"> ${id}. ${name}")
}
} catch {
case e: Exception => {
println(e.printStackTrace)
}
} finally {
println("Close...")
connection.close()
println(s"Connection valid: ${connection.isValid(5)}")
}
}
}
构建.sbt
version := "0.1.0-SNAPSHOT"
organization := "com.test"
scalaVersion := "2.12.19"
name := "Maria"
Compile / mainClass := Some("com.test.Maria")
assembly / mainClass := Some("com.test.Maria")
assembly / assemblyJarName := s"${name.value}-${version.value}.jar"
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-parser-combinators" % "2.3.0",
"org.mariadb.jdbc" % "mariadb-java-client" % "2.7.12"
)
excludeDependencies ++= Seq(
ExclusionRule("org.slf4j", "slf4j-api"),
ExclusionRule("org.slf4j", "jcl-over-slf4j")
)
事实证明,这是
build.sbt
文件破坏程序的情况。真实的应用程序(不是我的示例应用程序)使用 sbt-assemble 来创建一个 jar。使用 MergeStrategy
删除重复项的逻辑是删除 META-INF
目录中的 MariaDB 服务文件。如果没有这些,驱动程序不知道在哪里可以找到使用 caching_sha2_password 的类。