Docker环境下Redisson反序列化ClassNotFoundException问题求助
类加载器隔离问题
Spark在Docker环境下的类加载器层级可能存在隔离,比如Spark自带的org.apache.spark.util.MutableURLClassLoader和系统类加载器、线程上下文类加载器不一致。可以在异常触发的位置打印两个类加载器:Thread.currentThread().getContextClassLoader()和SmileJacksonCodec.class.getClassLoader(),对比是否为同一实例。另外要确认Redisson依赖是被Spark应用类加载器加载,而非仅被系统类加载器加载——Spark默认优先加载自身依赖,容易导致应用依赖被隔离。Jackson版本兼容性问题
Spark 3.4.0绑定Jackson 2.14.2,要检查你使用的Redisson版本是否与该Jackson版本兼容。部分Redisson版本的SmileJacksonCodec可能依赖特定Jackson版本,版本不匹配时可能出现隐性类加载错误(比如依赖的Jackson内部类不存在,表现为当前Codec类找不到)。可以用javap工具分析SmileJacksonCodec的字节码,确认它引用的Jackson类在2.14.2中是否存在。Docker镜像依赖完整性与路径问题
进入Docker容器,执行jar tf redisson-xxx.jar | grep SmileJacksonCodec,确认Redisson包中确实包含这个类。同时检查Redisson依赖在镜像中的存放路径是否被Spark类加载器扫描到——Spark应用依赖通常需要放在spark.jars指定路径,或者打包到应用jar的lib目录,路径不对的话类加载器找不到。反序列化时的类加载器指定问题
Redisson反序列化Config时,Jackson默认用线程上下文类加载器,但Spark线程模型中这个类加载器可能被切换。可以手动给Jackson指定应用类加载器:ObjectMapper mapper = new ObjectMapper(); mapper.setClassLoader(YourMainClass.class.getClassLoader()); Config config = mapper.readValue(new File("redis-config.yaml"), Config.class);另外检查
redis-config.yaml里的codec配置是否拼写正确,虽然本地正常,但Docker环境下可能因配置文件复制时的格式或内容错误导致类名解析失败。Jetty线程的类加载器上下文配置
Jetty在Spark环境下启动的处理线程,其上下文类加载器可能未设置为应用类加载器。可以在Jetty端点初始化时手动设置:Thread.currentThread().setContextClassLoader(getClass().getClassLoader());同时检查Jetty是否有自定义类加载器配置,导致Redisson的类无法被加载。
内容的提问来源于stack exchange,提问作者Chandan Gawri

