HiveJDBC与其他JDBC一起使用时出现java.lang.IllegalArgumentException: Bad URL format

问题描述:

程序中需要使用JDBC的方式同时访问Hive和MySQL,发现在获取MySQL连接的时候(DriverManager.getConnection方法)出现Hive的类中的Bad URL format异常。

代码如下:

 public Connection getMySqlConn() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(ConstantUtil.mysqlUrl, ConstantUtil.mysqlUsername, ConstantUtil.mysqlPassword);
        } catch (ClassNotFoundException e) {
            logger.error(e.getMessage(), e);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        }
        return conn;
    }

异常如下:

java.lang.IllegalArgumentException: Bad URL format
        at org.apache.hive.jdbc.Utils.parseURL(Utils.java:185)
        at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:84)
        at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:104)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:247)
        at com.xxx.util.MySqlUtil.getMySqlConn(MySqlUtil.java:33)
        at com.xxx.interceptor.TransformInterceptor.refreshApp(TransformInterceptor.java:151)
        at com.xxx.interceptor.TransformInterceptor.initialize(TransformInterceptor.java:42)
        at org.apache.flume.interceptor.InterceptorChain.initialize(InterceptorChain.java:74)
        at org.apache.flume.channel.ChannelProcessor.initialize(ChannelProcessor.java:68)
        at org.apache.flume.source.PollableSourceRunner.start(PollableSourceRunner.java:70)
        at org.apache.flume.lifecycle.LifecycleSupervisor$MonitorRunnable.run(LifecycleSupervisor.java:249)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

原因分析:

DriverManager.getConnection方法会使用url去尝试访问每个注册的JDBCDriver的connect方法,而JDBC的规范中要求该方法要判断url是否能够处理,不能处理要返回null。
然而,hive-jdbc在0.11.0版本中(具体受影响的版本范围未分析),调用其connect方法时,在url前缀非hive的情况下,是直接抛出IllegalArgumentException,而这个异常DriverManager并不会捕获,导致程序直接报错,不再尝试正确的MySQL的Driver。

解决办法:

(1)新版本的HiveJdbcDriver已修改这个问题。即先判断url前缀是否可以处理(处理不了返回null),并且将parseURL的异常修改为SQLException的子类(DriverManager会捕获)。
(2)将调用的代码改为,先获取你需要的Driver,再调用具体Driver的connect方法,这样DriverManager就不会去尝试调用每个Driver的connect方法了。代码如下:

public Connection getMySqlConn() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Driver driver = DriverManager.getDriver(ConstantUtil.mysqlUrl);
            java.util.Properties info = new java.util.Properties();
            info.put("user", ConstantUtil.mysqlUsername);
            info.put("password", ConstantUtil.mysqlPassword);
            conn = driver.connect(ConstantUtil.mysqlUrl, info);
        } catch (ClassNotFoundException e) {
            logger.error(e.getMessage(), e);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        }
        return conn;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值