惊!未实现Serializable竟让第三方接口回调全军覆没

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

前一段时间接收到异常报警,发现传递的类没有实现java.io.Serializable接口导致,调用失败。由于的第三方的统一问题,所以导致调第三方接口回调全军覆没。

从报错信息来,是Dubbo 序列化导致的。

02 问题追踪

从报错的信息中明显的可以看出就是需要实现java.io.Serializable 接口,查看的代码确认后,证实了第三方的jar 包中没有实现java.io.Serializable 接口。

2.1 源码追踪

从报错中可以追溯到:

com.alibaba.com.caucho.hessian.io.SerializerFactory#getDefaultSerializer

主要的方法:

java 复制代码
// cl 是不是 Serializable.class的实现类或者子类
Serializable.class.isAssignableFrom(cl)

isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系。

所以Dubbo框架会在序列化的时候,校验类是否实现java.io.Serializable。这个是框架行为,并不是所有的框架都会校验。

2.2 Serializable 深究

java.io.Serializable 到底是用来作什么的?

java.io.Serializable 接口是一个标记接口(没有定义任何方法),其主要作用是标识一个类的对象可以被序列化。序列化是指将对象转换为字节流的过程,以便存储到文件、数据库或通过网络传输,之后可以通过反序列化将字节流恢复为对象。

对象实现了java.io.Serializable 表示支持默认的序列化,如果不实现则无法直接序列化,需要借助三方库实现。

java 复制代码
@Data
@AllArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    
    String name;
    int age;
}

@Test
void test01() {
    User user = new User("鸣人", 18);
    System.out.println(user);
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
        oos.writeObject(user); // 成功
        oos.flush();

        byte[] bytes = outputStream.toByteArray();
        System.out.println(new String(bytes, StandardCharsets.UTF_8));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

实现Serializable接口执行正常

不实现Serializable接口执行异常

2.3 青睐的框架

java.io.Serializable 受很多流行框架的青睐。如,远程方法调用Dubbo、会话管理Spring Session、消息队列ActiveMQRabbitMQ、缓存持久化Redis、分布式事务Seata等,均需要校验对象是否实现java.io.Serializable 接口。

03 问题解决

找到问题的原因就可以对症下药解决问题了,但是我们遇到的问题是第三方没有实现java.io.Serializable 接口导致的。

本来想着要求对方解决,但是对方以需要开发评估为由婉拒,建议我们兼容处理。

怎么办呢?因为并不是第三方结果返回结果异常,人家是正常返回数据,只不过返回的数据在我们业务系统里传递的时候,导致序列化异常,所以人家并不是着急。

兼容的办法也很简单:直接使用已经实现序列化接口的类代替即可,通用的有java.util.HashMapcom.alibaba.fastjson.JSONObject

04 小结

出现这样的问题,主要就是第三方开发不规范导致的。既然作为提供给别人的SDK,就应该考虑到别人使用的便利性。

反过来讲,我们在和第三方对接时,使用第三方SDK时,里面的实体类能不能拿来直接用,需要我们判断一下,而不能盲目的直接使用。

看似一个小小的问题,平时可能不注意,自己开发的时候要不要实现java.io.Serializable,心里可能都没有谱。一旦发生线上故障,那就是大问题。所以我们要养成良好的编码习惯。

相关推荐
正在走向自律33 分钟前
从感知到自主决策:机器人技术的演进、核心架构与产业落地全景解析
架构·机器人·人形机器人·宇数机器人·医疗服务
名字还没想好☜39 分钟前
Next.js App Router 数据获取:fetch 缓存、revalidate 与 dynamic 一次讲清
前端
成都渲染101云渲染66665 小时前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
闲猫7 小时前
Spring AI 对接Deepseek ChatModel 聊天对话
java·前端·spring
木木学AI8 小时前
AI客服系统技术选型:Agentic架构与传统规则引擎的能力差异评估
人工智能·架构
自信的未来9 小时前
JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
java·前端·json
全栈前端老曹9 小时前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
zhangxingchao10 小时前
AI大模型核心八:从 Agent Skill、长文档 RAG 到知识库更新与训练策略
前端·人工智能·后端
zhangxingchao10 小时前
AI大模型核心七:从 Workflow、RAG、记忆治理到幂等性
前端·人工智能·后端
阿里嘎多学长11 小时前
2026-07-07 GitHub 热点项目精选
开发语言·程序员·github·代码托管