如何不替换驱动jar包解决旧版本mysql驱动引起的No columns to generate for ClassWriter问题
Posted 扫地增
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何不替换驱动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)
分析
因为笔者奉行一句话实践出真知,之前运行的任务就是最好的证明说明咱们的脚本绝对没有什么问题。因此出现这个问题我们要从系统服务和兼容性两个方面思考,所以在排查问题时笔者直接告诉他代码没有问题,是现有代码或者服务存在问题。
经过查询资料我们发现网上关于这个问题的说法五花八门,分析对比后结果发现,这个报错其实不是真正的报错。只是这段话刚好是报错代码的最后面,所以才被误以为这是一个独立的报错,这只是一类错误的统称,其实有很多不同的错误都会导致出现这个代码。
java.io.IOException: No columns to generate for ClassWriter
比如:
(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
我们发现这是一个下标越界的异常,结合当前我们对兼容性方向的怀疑,我们再次查看了表的schema,发现在映射关系中有一个字段使用的是json类型,出现了和驱动的类型会出现兼容性问题
解决
于是我们将该字段强转为varchar类型成功解决了问题。
总结
bug解决的核心还是日志+理论。加油吧兄弟萌!
以上是关于如何不替换驱动jar包解决旧版本mysql驱动引起的No columns to generate for ClassWriter问题的主要内容,如果未能解决你的问题,请参考以下文章
JAVA连接MYSQL数据库,如何导入驱动包?我是新手,求详细解答!