有趣的 Oracle JDBC 驱动包命名问题 - ojdbc6 和 ojdbc14 哪个新?!

有趣的 Oracle JDBC 驱动包命名问题 - ojdbc6 和 ojdbc14 哪个新?!

1 背景概述

最近协助一个小兄弟排查了某作业使用 sqoop 采集 oracle 数据的失败问题,问题现象,问题原因和解决方法都挺直观,但在此过程中发现了一个有趣的 Oracle JDBC 驱动包命名问题,不留意还真不好发现,故在次跟大家分享下。

2 问题现象

  • 某 sqoop import 作业导入 oracle 数据到 hdfs 时失败,核心报错提示 oracle jdbc 驱动找不到相关方法,如下所示:
- ERROR manager.OracleManager: Could not find method setSessionTimeZone in oracle.jdbc.driver.T4CConnection 
- java.lang.NoSuchMethodException:oracle.jdbc.driver.T4CConnection.setDefaultTimeZone(java.util. TimeZone)
  • 因为历史原因,该产品部分老版本还在使用老旧的 sqoop 技术栈,新版本已经切换使用了datax/spark等方案,大家在此不用纠结这点,事实上,该 Oracle JDBC 驱动版本问题,适用于所有 ORACLE 同步工具;
  • oracle jdbc 驱动找不到相关方法,详细报错日志如下:

23/11/15 10:58:40 INF.sqoop.Sqoop: Running sqoop version: 1.4.6-cdh5.16.1
23/11/15 10:58:40 WARN tool.BaseSqoopTool: Setting your password on the command-line is insecure. Consider using -P instead. 
23/11/15 10:58:40 INFO oracle.OraOopManagerFactory: Data Connector for Oracle and Hadoop is disabled.
23/11/15 10:58:40 INFO manager.SqlManager: Using default fetchSize of 1000
23/11/15 10:58:40 INFO tool. CodeGenTool: Beginning code generation
23/11/15 10:58:40 ERROR manager.OracleManager: Could not find method setSessionTimeZone in oracle.jdbc.driver.T4CConnection java.lang.NoSuchMethodException:oracle.jdbc.driver.T4CConnection.setDefaultTimeZone(java.util. TimeZone)
    at java.lang.Class.getMethod(Class.java.1786)
    at org.apache.sqoop.manager.OracleManager.setSessionTimeZone(OracleManager.java:407)
    at org.apache.sqoop.manager.OracleManager.makeConnection(OracleManager.java:341)
    at org.apache.sqoop.manager.GenericJdbcManager.getConnection(GenericJdbcManager.java:52)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:762)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:785)
    at org.apache.sqoop.manager.SqlManager.getColumnInfoForRawQuery(SqlManager.java:288)
    at org.apache.sqoop.manager.SqlManager.getColumnTypesForRawQuery(SqlManager.java:259)
    at org.apache.sqoop.manager.SqlManager.getColumnTypesForQuery(SqlManager.java:252)
    at org.apache.sqoop.manager.ConnManager.getColumnTypes(ConnManager.java:342)
    at org.apache.sqoop.orm.ClassWriter.getColumnTypes(ClassWriter.java:1858)
    at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1657)
    at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:106)
    at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:494)
    at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:621)
    at org.apache.sqoop.sqoop.run(Sqoop.java:147)
    at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
    at org.apache.sqoop.sqoop.runSqoop(Sqoop.java:183)
    at org.apache.sqoop.sqoop.runTool(Sqoop.java:234)
    at org.apache.sqoop.sqoop.runTool(Sqoop.java:243)
    at org.apach.sqoop.sqoop.main(Sqoop.java:252)
23/11/15 10:58:40 ERRO.manager.SqlManager: Error executing statement: java.sql.SQLException: java.lang.NoSuchMethodException:oracle.jdbc.driver.T4CConnection.setDefaultTimeZone(java.util.TimeZone)
Java.sql.SQLException: java.lang.NoSuchMethodException: oracle.jdbc.driver.T4CConnection. setDefaultTimezone(java.util.Timezone) 
  at org.apache.sqoop.manager.OracleManager.setSessionTimeZone(OracleManager.java:412)
  at org.apache.sqoop.manager.OracleManager.makeConnection(OracleManager.java:341)
  at org.apache.sqoop.manager.GenericJdbcManager.getConnection (GenericJdbcManager.java:52)
  at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:762)
  at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:785)
  at org.apache.sqoop.manager.SqlManager.getColumnInfoForRawQuery(SqlManager.java:288)

3. 问题原因

问题原因很简单:

  • sqoop 默认会在 $SQOOP_HOME/lib 目录下添加 mysql jdbc 相关驱动,但因为版权原因不会添加 ORACLE JDBC 相关驱动;
  • 用户手动添加 ORACLE JDBC 驱动时,应该使用 ojdbc6.jar,而不是 ojdbc14.jar,同时各个 worker 节点上述目录下,都要有添加上述驱动,而不是只有1个节点;
  • 问题原因的底层技术背景是,org.apache.sqoop.manager.OracleManager.setSessionTimeZone(OracleManager.java:412) 使用反射调用了 OracleConnection 类的方法 setSessionTimeZone;(Need to use reflection to call the method setSessionTimeZone on the OracleConnection class because oracle specific java libraries are not accessible in this context),其底层又会调用方法 setDefaultTimeZone, 在 ojdbc6.jar 中有该方法,而 ojdbc14.jar 没有该方法;
  • ojdbc14.jar 其实是2005年左右推出的,是针对 JDK1.4/JDK1.5的,而不是针对 JDK14的,ORACLE 官方也早就不支持该版本的驱动了;

4. 问题解决

问题解决也很简单,删除各个节点目录 $SQOOP_HOME/lib 下的 ojdbc14.jar,并上传 ojdbc6.jar 即可.

5. 盘点下 ORACLE JDBC 驱动常见版本及其对应的 JDK 版本

  • ORACLE JDBC 驱动的命名,一直以来遵循的都是 ojdbcx.jar,其中x代表最初针对的JDK版本;
  • 目前市面上可见的 ORACLE JDBC 驱动,及其对应的 JDK 版本如下:
ORACLE JDBC 驱动版本主要适配的JDK版本
ojdbc5.jarJDK5
ojdbc6.jarJDK6
ojdbc7.jarJDK7
ojdbc8.jarJDK8/JDK11
ojdbc11.jarJDK11/JDK17/JDK19/JDK21
ojdbc14.jarJDK1.4, 不是 JDK14!
  • 从上图可知,目前主要使用的 ORACLE JDBC 驱动版本有, ojdbc6.jar/ojdbc7/ojdbc8.jar/ojdbc11.jar;
  • 从上图可知,ojdbc14.jar 是2005年左右推出的,针对的是 JDK1.4,而不是 JDK14!!!
  • Oracle官方有说明:Since Oracle Database 11g Release 1, support for a version of JDK earlier than version 5.0 has been removed. Also, the ojdbc14.jar, ojdbc5.jar and classes12.jar files are no longer shipped. Instead, you can use the ojdbc6.jar and ojdbc7.jar files, which are shipped with Oracle Database 12c;



  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要让 Pinpoint Oracle JDBC Driver Plugin 支持 ojdbc6,需要进行以下步骤: 1. 在 Pinpoint 的安装目录下创建 `plugins` 目录。 2. 下载 Pinpoint Oracle JDBC Driver Plugin 的源代码,并将 `pinpoint-oracle-jdbc-driver-plugin-xxx.jar` 文件放置在 `plugins` 目录中。 3. 打开 `plugins` 目录下的 `pinpoint-oracle-jdbc-driver-plugin-xxx.jar` 文件,将其中的 `pinpoint.config` 文件解压到任意目录中。 4. 在 `pinpoint.config` 文件中,指定使用 ojdbc6 驱动。例如: ``` profiler.jdbc.driver.class.name=oracle.jdbc.driver.OracleDriver profiler.jdbc.driver.path=/path/to/ojdbc6.jar ``` 其中 `/path/to/ojdbc6.jar` 是 ojdbc6.jar 文件的路径。 5. 将修改后的 `pinpoint.config` 文件重到 `pinpoint-oracle-jdbc-driver-plugin-xxx.jar` 文件中。 6. 启动 Pinpoint 代理程序,并指定使用 `plugins` 目录中的插件: ``` java -javaagent:/path/to/pinpoint-agent/pinpoint-bootstrap.jar \ -Dpinpoint.agentId=your_agent_id \ -Dpinpoint.applicationName=your_application_name \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleDriverPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OraclePreparedStatementPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleCallableStatementPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleStatementPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleDataSourcePlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleConnectionPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleResultSetPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleJdbcUrlPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleJdbcUrlParserPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OraclePreparedStatementBindingMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleCallableStatementBindingMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleStatementBindingMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OraclePreparedStatementExecuteQueryMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleCallableStatementExecuteQueryMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleStatementExecuteQueryMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OraclePreparedStatementExecuteUpdateMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleCallableStatementExecuteUpdateMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleStatementExecuteUpdateMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OraclePreparedStatementExecuteMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleCallableStatementExecuteMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleStatementExecuteMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleConnectionCreateStatementMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleConnectionPrepareStatementMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleDataSourceGetConnectionMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.plugin.jdbc.oracle.OracleResultSetNextMethodFilter \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin \ -Dpinpoint.plugin.include=com.navercorp.pinpoint.bootstrap.plugin.transformer.PinpointClassFileTransformer \ -Dpinpoint.agent.plugins=/path/to/pinpoint-agent/plugins ``` 其中 `/path/to/pinpoint-agent` 是 Pinpoint 代理程序所在的路径,`your_agent_id` 和 `your_application_name` 分别是您为应用程序指定的代理 ID 和应用程序名称。 7. 重启应用程序,使配置生效。 这样就可以让 Pinpoint Oracle JDBC Driver Plugin 支持 ojdbc6 驱动了。注意,在使用 Pinpoint 插件时,需要启用 Pinpoint 代理程序,并将插件添加到 JVM 参数中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明哥的IT随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值