sbt-Assembly 破坏 jar 中的库导入

问题描述 投票:0回答:1

我正在尝试在 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
文件吗?

尝试过:

  1. 更换图书馆。
  2. 尝试过不同版本的 MariaDB Connector/J。
  3. 当我使用
    mysql_native_password
    auth 插件时连接到 MySQL 8。
  4. 连接到MySQL服务器5.7,但反复无法连接到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")
)
scala sbt sbt-assembly mariadb-connector
1个回答
0
投票

事实证明,这是

build.sbt
文件破坏程序的情况。真实的应用程序(不是我的示例应用程序)使用 sbt-assemble 来创建一个 jar。使用
MergeStrategy
删除重复项的逻辑是删除
META-INF
目录中的 MariaDB 服务文件。如果没有这些,驱动程序不知道在哪里可以找到使用 caching_sha2_password 的类。

© www.soinside.com 2019 - 2024. All rights reserved.