同时使用hive和mysql jdbc驱动程序

qrjkbowd  于 2021-06-28  发布在  Hive
关注(0)|答案(3)|浏览(526)

热释光;dr:同时使用hive和mysql jdbc有问题吗?
我正在开发一个应用程序,它使用mysql jdbc驱动程序执行几个sql查询,然后还使用hivejdbc发送另一个配置单元查询。
现在发生的是mysql查询工作正常,当代码尝试执行配置单元查询时,它抛出以下异常:

com.mysql.cj.core.exceptions.WrongArgumentException: Connector/J cannot handle a database URL of type 'jdbc:hive2:'.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.cj.core.exceptions.ExceptionFactory.createException(ExceptionFactory.java:54)
    at com.mysql.cj.core.conf.url.ConnectionUrl$Type.fromValue(ConnectionUrl.java:149)
    at com.mysql.cj.core.conf.url.ConnectionUrl.getConnectionUrlInstance(ConnectionUrl.java:193)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:195)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at company.services.HiveV2Provider.createConnection(HiveProvider.scala:105)
    at company.services.HiveProvider$class.loanConnection(HiveProvider.scala:66)

现在,在抛出此异常之后,查询将正确执行。
我的猜测是,由于我同时加载mysql和hive驱动程序,mysql驱动程序试图首先运行这个查询,但是当它遇到hiveurl时抛出这个异常,然后hive驱动程序看到它并正确地执行查询
我是这样执行mysql代码的:

val query = ... // query is created here
var mysqlConn: Connection = null
var stmt: Statement = null
try {
  Class.forName("com.mysql.jdbc.Driver")
  mysqlConn = DriverManager.getConnection(mysqlAddress, username, password)
  stmt = mysqlConn.createStatement()
  val rs = stmt.executeQuery(query)
  val returnVal = someResultSetHandlingFunction(rs)
  rs.close()
  returnVal
} catch {
  case NonFatal(e) =>
    logWarning(s"Failed to execute query on: $mysqlAddress", e)
    throw e
} finally {
  if (mysqlConn != null) {
    mysqlConn.close()
  }
}

我的配置单元代码看起来相同,只是驱动程序名为: org.apache.hive.jdbc.HiveDriver (它与 jdbc:hive2://someurl )
版本:
hive是hive-jdbc-1.1.0-cdh5.7.1
mysql是mysql connector java 6.0.4
有人知道有没有办法避免收到这个例外?加载两个不同的jdbc驱动程序有问题吗?阅读其他一些类似的问题,我得到的印象是,这应该不是一个问题
只是一些澄清:
我知道直接使用jdbc可能不是最好的方法,但是我正在检查一些东西,jdbc可以胜任这个任务
我正在使用scala,但我认为它对这个问题不重要
提前谢谢

yvfmudvl

yvfmudvl1#

Class.forName("com.mysql.jdbc.Driver")

将在drivermanager中注册jdbc驱动程序。然后将配置单元连接uri放入

DriverManager.getConnection(mysqlAddress, username, password)

在这种情况下会出现异常。
在检查uri之后,为什么不将调用委托给特定的jdbc驱动程序,如:

if (uri.contains("hive")){
       //call Hive JDBC
    }

    else if (uri.contains("mysql")){
       //call Mysql JDBC
    }
bwntbbo3

bwntbbo32#

我差点忘了回答我的问题
所以这个问题可能与这个bug有关。当我面对这个问题的时候,我没有注意到它只是一个堆栈跟踪打印,而不是一个实际的失败,所以问题没有我想象的那么严重。
不管怎样,我看到在一些特定的版本中,这个问题已经解决了,正如你在这里看到的,所以我把mysql的版本改成了5.1.9(因为我不需要更高的版本来处理任何特定的问题),堆栈跟踪失败就消失了。
如果有人有更优雅的解决方案,我会很高兴的
干杯

h6my8fg2

h6my8fg23#

我在使用mssqlserverjdbc驱动程序时也遇到了同样的问题。记录了相同的错误,但一切正常。
根据此microsoft页面:
在JDBCAPI4.0中,drivermanager.getconnection方法得到了增强,可以自动加载jdbc驱动程序。因此,当使用sqljdbc4.jar、sqljdbc41.jar或sqljdbc42.jar类库时,应用程序不需要调用class.forname方法来注册或加载驱动程序。
所以我试着移除 Class.forName 刚打电话过来 DriverManager.getConnection . 一切正常,我再也不会犯恼人的错误了。
我相信驱动程序本身必须包含一个“meta-inf/services/java.sql.driver”文件,该文件将自己注册为一个有效的jdbc驱动程序,因此它不一定对您有用,但对sql server驱动程序用户来说,这是一种可行的方法。
顺便说一句:我注意到drivermanager.getconnection在第一次调用驱动器时要花费更多的时间(6或7秒)。后续通话正常。根据您的应用程序,这可能是一个问题。

相关问题