惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
WordPress大学
WordPress大学
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
博客园 - Franky
博客园 - 司徒正美
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
Jina AI
Jina AI
Last Week in AI
Last Week in AI
雷峰网
雷峰网
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX

博客园 - 青石路

好好的OceanBase官方驱动你不用,非要用第三方驱动,ArrayIndexOutOfBoundsException了吧 如果写Redis序列化与读Redis序列化不一致,你觉得会发生什么 记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来 Claude Code安装,接入阿里云百炼模型,蹭蹭免费额度 异源数据同步 → 记一次 DataX 已同步数据量优化 明明连接的是Redis的DB0,为什么能查到DB3的数据? TINYINT(1) 类型的字段,明明数据存的是 2,为什么查出来是 true 用了MySQL的INSERT ON DUPLICATE KEY UPDATE,怎么还报唯一索引冲突错误 那些年不该放到事务中的操作,你实现过哪些 关于布尔类型的变量不要加 is 前缀,被网友们吐槽了,特来完善下 都说了布尔类型的变量不要加 is 前缀,非要加,这不是坑我了嘛 安全漏洞修复导致SpringBoot2.7与Springfox不兼容,问题排查与处理 记一次SQL隐式转换导致精度丢失问题的排查 → 不规范就踩坑 经由同个文件多次压缩的文件MD5都不一样问题排查,感慨AI的强大! 记一次cannot access its superinterface问题的的排查 → 强如Spring也一样写Bug SpringBoot支持Kafka多源配置的同时还要支持启停配置化,是真的会玩 如果XXL-JOB执行器在执行某任务中被重启了,重启后该任务能够被自动弥补调度吗 Spring Boot读取外部配置文件失败,原因绝对出乎你意料 不依赖 Spring,你会如何自实现 RabbitMQ 消息的消费(一) 异源数据同步 → DataX 同步启动后如何手动终止? 异源数据同步 → 如何获取 DataX 已同步数据量? 记一次 RabbitMQ 消费者莫名消失问题的排查 不升级 POI 版本,如何生成符合新版标准的Excel 2007文件 以MySQL为例,来看看maven-shade-plugin如何解决多版本驱动共存的问题? maven 插件之 maven-shade-plugin,解决同包同名 class 共存问题的神器
记一次Qoder排查mave-shade-plugin只重定向部分package导致的...
青石路 · 2026-07-28 · via 博客园 - 青石路

开心一刻

小王牙龈发炎,去了个私立牙科就诊

大夫:拔了吧

小王:以前没有拔过牙,我害怕...

大夫:不用紧张,我也是第一次拔

护士问大夫:麻药打嘴里,还是打外面?

大夫:打腿上吧,一会别让他跑了

进了贼窝

问题背景

基于 DataX 实现的离线同步,公司开发环境、测试环境从 Oracle 19c 读取 CLOB 类型的字段都是正常的、

包括已接入的客户都是能正常读取的,但这两天接入的一个新客户,出现了读取失败的问题

java.lang.NoSuchMethodError: oracle.sql.CLOB.<init>(Loracle/jdbc/OracleConnection;[BS)V
	at oracle.jdbc.driver.ClobAccessor.getCLOB_(ClobAccessor.java:240)
	at oracle.jdbc.driver.ClobAccessor.getCLOB(ClobAccessor.java:264)
	at oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:454)
	at oracle.jdbc.driver.GeneratedStatement.getString(GeneratedStatement.java:287)
	at oracle.jdbc.driver.GeneratedScrollableResultSet.getString(GeneratedScrollableResultSet.java:374)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.buildRecord(CommonRdbmsReader.java:268)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.transportOneRecord(CommonRdbmsReader.java:238)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.startRead(CommonRdbmsReader.java:210)
	at com.alibaba.datax.plugin.reader.oraclereader.OracleReader$Task.startRead(OracleReader.java:122)
	at com.alibaba.datax.core.taskgroup.runner.ReaderRunner.run(ReaderRunner.java:57)
	at java.lang.Thread.run(Thread.java:750)
 - java.lang.NoSuchMethodError: oracle.sql.CLOB.<init>(Loracle/jdbc/OracleConnection;[BS)V
	at oracle.jdbc.driver.ClobAccessor.getCLOB_(ClobAccessor.java:240)
	at oracle.jdbc.driver.ClobAccessor.getCLOB(ClobAccessor.java:264)
	at oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:454)
	at oracle.jdbc.driver.GeneratedStatement.getString(GeneratedStatement.java:287)
	at oracle.jdbc.driver.GeneratedScrollableResultSet.getString(GeneratedScrollableResultSet.java:374)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.buildRecord(CommonRdbmsReader.java:268)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.transportOneRecord(CommonRdbmsReader.java:238)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.startRead(CommonRdbmsReader.java:210)
	at com.alibaba.datax.plugin.reader.oraclereader.OracleReader$Task.startRead(OracleReader.java:122)
	at com.alibaba.datax.core.taskgroup.runner.ReaderRunner.run(ReaderRunner.java:57)
	at java.lang.Thread.run(Thread.java:750)

	at com.alibaba.datax.common.exception.DataXException.asDataXException(DataXException.java:48)
	at com.alibaba.datax.core.job.scheduler.processinner.ProcessInnerScheduler.dealFailedStat(ProcessInnerScheduler.java:39)
	at com.alibaba.datax.core.job.scheduler.AbstractScheduler.schedule(AbstractScheduler.java:99)
	at com.alibaba.datax.core.job.JobContainer.schedule(JobContainer.java:532)
	at com.alibaba.datax.core.job.JobContainer.start(JobContainer.java:116)
	at com.alibaba.datax.core.Engine.start(Engine.java:89)
	at com.alibaba.datax.core.Engine.entry(Engine.java:170)
	at com.alibaba.datax.core.Engine.main(Engine.java:209)
Caused by: java.lang.NoSuchMethodError: oracle.sql.CLOB.<init>(Loracle/jdbc/OracleConnection;[BS)V
	at oracle.jdbc.driver.ClobAccessor.getCLOB_(ClobAccessor.java:240)
	at oracle.jdbc.driver.ClobAccessor.getCLOB(ClobAccessor.java:264)
	at oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:454)
	at oracle.jdbc.driver.GeneratedStatement.getString(GeneratedStatement.java:287)
	at oracle.jdbc.driver.GeneratedScrollableResultSet.getString(GeneratedScrollableResultSet.java:374)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.buildRecord(CommonRdbmsReader.java:268)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.transportOneRecord(CommonRdbmsReader.java:238)
	at com.alibaba.datax.plugin.rdbms.reader.CommonRdbmsReader$Task.startRead(CommonRdbmsReader.java:210)
	at com.alibaba.datax.plugin.reader.oraclereader.OracleReader$Task.startRead(OracleReader.java:122)
	at com.alibaba.datax.core.taskgroup.runner.ReaderRunner.run(ReaderRunner.java:57)
	at java.lang.Thread.run(Thread.java:750)

提示找不到 CLOB 构造函数

当客户反馈这个问题后,我第一时间在公司环境进行测试,并未出现问题

也反编译了 CLOB.class,其构造函数有好几个

12.2.0.1_CLOB构造函数

怎么就 NoSuchMethodError 了呢?

20240115000802

Qoder 排查

当我陷入迷茫,没有可排查方向时,我想到了 AI,正好前不久接入了 Qoder,抱着试一试的心态,我开始了与 Qoder 的对话

我直接提问:

结合相关上下文分析下,从 oracle 19c 读取 clob 类型的字段,为什么会报错。并附上了异常堆栈信息

开始询问qoder

很快 Qoder 给了回复

qoder分析_23版本CLOB

注意:

为了兼容不同版本的 Oracle,我们同时引入了 ojdbc8 12.2.0.1ojdbc8 23.5.0.24.07

直接依赖这两个的话,依赖会冲突,生效的只会是其中某一个:结合实例看 maven 传递依赖与优先级,难顶也得上丫

所以我们利用 maven-shade-plugin 对 23.5.0.24.07 的 package 进行了重定向:maven 插件之 maven-shade-plugin,解决同包同名 class 共存问题的神器

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.6.0</version>
            <executions>
                <execution>
                    <!-- 和 package 阶段绑定 -->
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>oracle.jdbc</pattern>
                                <shadedPattern>oracle.jdbc23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.net</pattern>
                                <shadedPattern>oracle.net23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.security</pattern>
                                <shadedPattern>oracle.security23</shadedPattern>
                            </relocation>
                        </relocations>
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.MF</exclude>
                                    <exclude>META-INF/*.txt</exclude>
                                    <exclude>META-INF/*.bin</exclude>
                                    <exclude>META-INF/*.properties</exclude>
                                </excludes>
                            </filter>
                        </filters>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/></div>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Qoder 这个分析一针见血,但他分析反了,我选中 OracleReader.java 的代码

private DataBaseType getDatabaseType() {
    Integer dbVersion = this.originalConfig.getInt(CommonConstant.DB_MAJOR_VERSION);
    if (Objects.isNull(dbVersion)) {
        return DataBaseType.Oracle;
    }
    if (dbVersion >= 23) {
        return DataBaseType.Oracle23;
    }
    return DataBaseType.Oracle;
}

补充道:

dbVersion 的值是19,用的应该是12.2.0.1的 oracle.jdbc.driver.ClobAccessor,不会用 jdbc23

Qoder 继续他的分析

补充19c生效的是12驱动而非23

至此,问题原因是不是已经找到?

我总结下

重定向 23 版本 package 的时候,我们并未对其 oracle.sql 包重定向,所以 classpath 上有两个 oracle.sql.CLOB 类,一个是 12 版本的,一个是 23 版本的

JVM 类加载时如果先加载到 23 版本的 oracle.sql.CLOB,就不会继续加载 12 版本的 oracle.sql.CLOB,那么 12 版本的 ClobAccessor 调用 new CLOB(connection, bytes, short) 时,用到的就是 23 版本的 CLOB,而 23 版本的 CLOB 构造函数 CLOB(OracleConnection conn, byte[] lob_descriptor, short csform) 的 OracleConnection 是什么类型?

oracle.jdbc23.OracleConnection(因为我们将 23 版本的 oracle.jdbc 重定向成 oracle.jdbc23 了),而 ClobAccessor 调用 new CLOB(connection, bytes, short) 时,connection 类型是什么?是不是 12 版本的 oracle.jdbc.OracleConnection

总结就是:12 版本的 ClobAccessor 拿着 oracle.jdbc.OracleConnection 类型的参数去调构造函数,但 JVM 先加载的 23 版本的 CLOB 构造函数只接受 oracle.jdbc23.OracleConnection 类型,参数类型不匹配,所以 NoSuchMethodError

最后我又问了一个问题:

为什么有的环境会出现 java.lang.NoSuchMethodError: oracle.sql.CLOB.(Loracle/jdbc/OracleConnection;[BS)V 问题,有的环境又正常

Qoder 很快给出了回答

为什么有些正常有些不正常

这些影响 classpath 顺序的因素,是不是又触及你们的知识盲区了?

好难 不该学编程的

问题修复

问题原因已经找到,修复自然就简单了,将 23 版本的包都重定向

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.6.0</version>
            <executions>
                <execution>
                    <!-- 和 package 阶段绑定 -->
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>oracle.jdbc</pattern>
                                <shadedPattern>oracle.jdbc23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.net</pattern>
                                <shadedPattern>oracle.net23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.security</pattern>
                                <shadedPattern>oracle.security23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.sql</pattern>
                                <shadedPattern>oracle.sql23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.core</pattern>
                                <shadedPattern>oracle.core23</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>oracle.jpub</pattern>
                                <shadedPattern>oracle.jpub23</shadedPattern>
                            </relocation>
                        </relocations>
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.MF</exclude>
                                    <exclude>META-INF/*.txt</exclude>
                                    <exclude>META-INF/*.bin</exclude>
                                    <exclude>META-INF/*.properties</exclude>
                                </excludes>
                            </filter>
                        </filters>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/></div>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

这样 12 版本与 23 版本之间互不干扰,自然就没有 NoSuchMethodError 问题了

当然,重定向也可以简化

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.6.0</version>
            <executions>
                <execution>
                    <!-- 和 package 阶段绑定 -->
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>oracle</pattern>
                                <shadedPattern>oracle23</shadedPattern>
                            </relocation>
                        </relocations>
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.MF</exclude>
                                    <exclude>META-INF/*.txt</exclude>
                                    <exclude>META-INF/*.bin</exclude>
                                    <exclude>META-INF/*.properties</exclude>
                                </excludes>
                            </filter>
                        </filters>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/></div>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

只要保证重定向后的包名与其他包名不重名,那就没问题

总结

  1. maven-shade-plugin 很强,很好用,但业务细节仍需注意
  2. AI 是趋势,阻挡不了就好好拥抱,早用早享受