Spring Boot 启动时报 NumberFormatException: YES,最重要的不是异常栈有多长,而是 YES 在什么阶段被当成数字读取。这次故障发生在分片数据源加载表元数据时,不是在业务 INSERT 执行时。
当时的依赖组合
Spring Boot 2.1.4
Sharding-JDBC 4.0.0-RC3
mysql-connector-java 8.0.15
创建 shardingDataSource 失败,外层连带出现 Mapper、SqlSessionFactory 和 Controller 的依赖创建异常。这些是初始化失败向外传播的结果,不应逐个改业务 Bean。
从最内层向外读
下面保留原日志中足够定位的调用顺序,省略重复的 Spring 依赖创建栈:
NumberFormatException: For input string: "YES"
Double.parseDouble
MysqlTextValueDecoder.decodeDouble
StringConverter.createFromBytes
ResultSetImpl.getBoolean
DelegatingResultSet.getBoolean
TableMetaDataLoader.getColumnMetaDataList
TableMetaDataLoader.createTableMetaData
TableMetaDataInitializer.load
SpringBootConfiguration.shardingDataSource
这里可以确认:布尔读取经过驱动转换时,进入了数字解析路径,输入恰好是 YES;再向上是 Sharding-JDBC 表元数据加载。仅凭这个栈还不足以确认具体列、驱动选项及上游修复提交,不应编造一个已锁定的 JDBC 字段原因。
当时只调整了候选版本
查到相近问题后,我把 Sharding-JDBC 从 4.0.0-RC3 改成 4.0.0-RC2,当时应用能够启动。这个结果说明依赖组合值得检查,但不是“8.0.15 永远不能搭配 RC3”的普遍证明。
RC2 是 2019 年的历史绕过,不是当前生产选型建议。启动成功也还不代表查询、路由和主键生成都通过。
遇到同类问题怎样收窄
先记录实际解析出来的依赖,而非只看 pom 中一个版本号。Maven 可用下面的只读命令查看相关传递依赖:
mvn dependency:tree -Dincludes=org.apache.shardingsphere:*,mysql:mysql-connector-java,org.apache.commons:commons-dbcp2
再固定服务端版本、表结构、连接参数及其他依赖,在隔离环境逐项比较;同一时间改驱动和中间件,会失去判断依据。若对照版本说明或源码,应使用准确 tag,不能拿新版本实现反推旧候选版一定有相同逻辑。
这次记录的可复用方法是:找出最内层转换失败,再分清框架初始化与业务调用。不要看到最外层 Mapper 创建失败,就先改 SQL 或数据库字段。