K8s从1.21升级到1.23后org.json.JSONObject出现NoSuchMethodError
问题核心
Spring Boot应用中jsonObject.put("some_name", someList);代码(依赖org.json:json:20220320)在K8s从1.21升级到1.23(同步升级JDK至17.0.6+10)后抛出NoSuchMethodError,本地测试两个JDK版本均正常,Maven依赖树无异常,需重点排查容器环境中的实际依赖加载情况。
具体排查步骤
检查容器内实际加载的org.json jar版本
在运行中的Pod容器内执行命令,定位应用实际使用的JSONObject类来源:# 进入目标Pod容器 kubectl exec -it <pod-name> -- /bin/sh # 查找应用jar中的org.json类路径 jar tf /path/to/your/app.jar | grep "org/json/JSONObject.class"也可在应用报错代码附近临时添加日志,输出类的代码源位置:
System.out.println(JSONObject.class.getProtectionDomain().getCodeSource().getLocation());确认是否加载了无
put(String, Collection)方法的旧版本org.json jar(如20200518及更早版本)。验证打包后的应用jar依赖完整性
本地解压应用jar,检查BOOT-INF/lib目录下是否存在多个版本的org.json:jsonjar,确认版本是否为20220320。同时检查Maven打包插件(如spring-boot-maven-plugin)配置,排查是否存在依赖遗漏或冲突的打包逻辑。排查K8s容器的类路径配置
检查Pod的启动命令、环境变量(如CLASSPATH)是否被修改,是否有额外的jar路径被添加到类路径中导致旧版本org.json被优先加载。同时排查是否有sidecar容器或集群配置注入了额外依赖包。在容器镜像中复现问题
使用与K8s集群相同的基础镜像,本地构建容器并运行应用,确认是否能复现异常,排除K8s集群特殊配置(如网络挂载卷、安全策略)的影响。检查JDK发行版与配置差异
确认容器内的JDK发行版是否与本地一致(如OpenJDK、Corretto等),检查JVM启动参数是否有模块化相关配置(如--module-path),这类参数可能改变类加载顺序,导致旧版本类被加载。排查第三方依赖的隐性引入
执行mvn dependency:tree -Dincludes=org.json:json,仔细检查是否有第三方依赖间接引入了旧版本的org.json。即使本地依赖树显示正常,也可能存在打包时依赖范围配置错误(如provided或runtime导致依赖未被正确打包)。
内容的提问来源于stack exchange,提问作者aug

