• 如何不替换驱动jar包解决旧版本mysql驱动引起的No columns to generate for ClassWriter问题


    背景

    近期笔者离职入职了一家新公司,公司大数据从0到1,目前处于疯狂的数仓建设阶段,今天有同事在使用sqoop导数据时遇到了bug。发现一直使用的好好的导数据脚本突然报错了。当前已经有几百张表在正常使用脚本导数据了,基于此我们来分析问题所在。

    问题

    我们查看日志发现日志出现如下报错:

    	2022-08-04 11:43:52,019 INFO  [main] manager.SqlManager (SqlManager.java:execute(776)) - Executing SQL statement: 
    	    select 
    	    xxxx
    	    from contract
    	    where 1=1
    	     OR  (1 = 0) 
    	2022-08-04 11:43:52,023 ERROR [main] manager.SqlManager (LoggingUtils.java:logAll(43)) - Error executing statement: java.sql.SQLException: program err:java.lang.IndexOutOfBoundsException: Index: 26, Size: 26
    	java.sql.SQLException: program err:java.lang.IndexOutOfBoundsException: Index: 26, Size: 26
    		at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
    		at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
    		at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
    		at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
    		at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1399)
    		at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:857)
    		at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2323)
    		at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:777)
    		at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:786)
    		at org.apache.sqoop.manager.SqlManager.getColumnInfoForRawQuery(SqlManager.java:289)
    		at org.apache.sqoop.manager.SqlManager.getColumnTypesForRawQuery(SqlManager.java:260)
    		at org.apache.sqoop.manager.SqlManager.getColumnTypesForQuery(SqlManager.java:253)
    		at org.apache.sqoop.manager.ConnManager.getColumnTypes(ConnManager.java:336)
    		at org.apache.sqoop.orm.ClassWriter.getColumnTypes(ClassWriter.java:1872)
    		at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1671)
    		at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:106)
    		at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:501)
    		at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:628)
    		at org.apache.sqoop.Sqoop.run(Sqoop.java:147)
    		at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
    		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.apache.sqoop.Sqoop.main(Sqoop.java:252)
    	2022-08-04 11:43:52,025 ERROR [main] tool.ImportTool (ImportTool.java:run(634)) - Import failed: java.io.IOException: No columns to generate for ClassWriter
    		at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1677)
    		at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:106)
    		at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:501)
    		at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:628)
    		at org.apache.sqoop.Sqoop.run(Sqoop.java:147)
    		at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
    		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.apache.sqoop.Sqoop.main(Sqoop.java:252)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    分析

    因为笔者奉行一句话实践出真知,之前运行的任务就是最好的证明说明咱们的脚本绝对没有什么问题。因此出现这个问题我们要从系统服务和兼容性两个方面思考,所以在排查问题时笔者直接告诉他代码没有问题,是现有代码或者服务存在问题。
    经过查询资料我们发现网上关于这个问题的说法五花八门,分析对比后结果发现,这个报错其实不是真正的报错。只是这段话刚好是报错代码的最后面,所以才被误以为这是一个独立的报错,这只是一类错误的统称,其实有很多不同的错误都会导致出现这个代码。

     java.io.IOException: No columns to generate for ClassWriter
    
    • 1

    比如:
    (1)由于mysql现在是高版本,使用的驱动mysql-connector-java.jar的旧版本bug导致,或者oracal的驱动,主要会出现以前不支持的数据类型等现在支持了。
    (2)数据库的IP/用户名/密码/数据库名称 错误导致连接不上
    (3)sqoop export时,没有在目的库建好表
    大家要看清楚,自己的错到底是什么错。千万不可被大段的错误误导。
    所以笔者注意到我们的报错前面有一个错误说的是:

     Error executing statement: java.sql.SQLException: program err:java.lang.IndexOutOfBoundsException: Index: 26, Size: 26
    
    • 1

    我们发现这是一个下标越界的异常,结合当前我们对兼容性方向的怀疑,我们再次查看了表的schema,发现在映射关系中有一个字段使用的是json类型,出现了和驱动的类型会出现兼容性问题

    解决

    于是我们将该字段强转为varchar类型成功解决了问题。

    总结

    bug解决的核心还是日志+理论。加油吧兄弟萌!

  • 相关阅读:
    使用sql判断两段时间是否重叠
    灵感收集·创意写作软件评测:Flomo、Obsidian Memo、Napkin、FlowUs
    Java 设计模式(上)
    PyTorch实现苹果M1芯片GPU加速:训练速度提升7倍,性能最高提升21倍
    Redis持久化策略AOF、RDB详解及源码分析
    【YOLOv7】使用 YOLOv7 做目标检测 (使用自己的数据集 + 图解超详细)
    [SWPU2019]Web3
    java计算机毕业设计医院人事档案管理系源代码+系统+数据库+lw文档
    kotlin集合(Collections)
    注意:Spring Boot 2.7开始spring.factories不推荐使用了,接下来这么玩...
  • 原文地址:https://blog.csdn.net/qq_41018861/article/details/126157047