博主介绍:✌全网粉丝24W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌
技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。
感兴趣的可以先关注收藏起来,在工作中、生活上等遇到相关问题都可以给我留言咨询,希望帮助更多的人。
使用DateUtil.isSameDay方法判断秒级时间戳是否属于同一天踩过的坑
- 一、背景描述
- 二、异常分析
- 三、常见原因与解决方案
-
- [3.1 类路径缺失(最常见)](#3.1 类路径缺失(最常见))
- [3.2 包名或类名不一致](#3.2 包名或类名不一致)
- [3.3 使用了未注册的类(需要 Schema 注册)](#3.3 使用了未注册的类(需要 Schema 注册))
- [3.4 混淆或热加载环境(如 OSGi、Spring Boot Devtools)](#3.4 混淆或热加载环境(如 OSGi、Spring Boot Devtools))
- [3.5 使用了 Protostuff 的兼容模式(lite)](#3.5 使用了 Protostuff 的兼容模式(lite))
- 四、总结
一、背景描述
使用工具 Hutool
工具中的 DateUtil.isSameDay()
方法判断多个秒级时间戳是否属于同一天的功能,在本地windows11环境中使用没有遇到问题,部署到测试环境(Red Hat Enterprise Linux 8.10版本)也没有遇到问题。但是部署到生产环境就会遇到相同的秒级时间戳不属于同一天的情况。
比如以下几个时间戳:[1790650899, 1790650899, 1790654673, 1790658273, 1790658273, 1790661873] 和 1790611200】
二、异常分析
java
java.lang.ClassNotFoundException: com.example.MyClass
这意味着 Protostuff 在尝试通过反射加载类 com.example.MyClass
的时候失败了,JVM 找不到这个类。
三、常见原因与解决方案
3.1 类路径缺失(最常见)
确保反序列化端的 classpath 中包含你要反序列化的类(例如:MyClass.class
)。
检查项:
- 是否打包/部署了包含
com.example.MyClass
的 jar 包? - 是否在运行环境中正确引入了该类所在的模块?
解决方案:
将包含该类的 jar 文件添加到项目的依赖中(Maven、Gradle 或手动添加)。
3.2 包名或类名不一致
Protostuff 默认会根据类名和包名进行序列化/反序列化。如果你在不同的项目或模块中使用了相同类名但不同包名,也会导致找不到类。
示例:
- 序列化端:
com.example.model.MyClass
- 反序列化端:
com.test.model.MyClass
虽然类结构一样,但由于包名不同,Protostuff 会认为是两个类。
解决方案:
- 确保两端类的 全限定类名完全一致。
- 或者使用自定义 Schema 来绑定字段,而不是依赖类本身。
3.3 使用了未注册的类(需要 Schema 注册)
Protostuff 有些模式下(如 RuntimeSchema
) 需要提前注册类,否则无法识别。
示例代码(错误写法):
java
MyClass obj = new MyClass();
byte[] data = ProtostuffIOUtil.toByteArray(obj, someSchema, buf);
// 反序列化时如果 someSchema 不匹配或未注册,就会出问题
解决方案:
使用 RuntimeSchema
并确保类已注册:
java
Schema<MyClass> schema = RuntimeSchema.getSchema(MyClass.class);
MyClass myObj = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, myObj, schema);
或者更简单的方式(适用于已知类型):
java
MyClass obj = new MyClass();
byte[] data = ProtostuffSerializer.serialize(obj); // 内部自动处理 Schema
MyClass newObj = ProtostuffSerializer.deserialize(data, MyClass.class);
3.4 混淆或热加载环境(如 OSGi、Spring Boot Devtools)
某些框架或工具会对类进行混淆、隔离或重新加载,可能导致类无法被正常加载。
解决方案:
- 禁用热加载测试是否还报错(比如 Spring Boot Devtools)
- 检查 OSGi 插件中的类可见性配置
- 使用显式 Schema 替代基于类的自动推导
3.5 使用了 Protostuff 的兼容模式(lite)
Protostuff 有两个版本:标准版(full)和轻量版(lite),后者不支持一些高级特性,可能导致类解析失败。
解决方案:
确认你的 Protostuff 版本和使用方式是否一致,推荐使用完整版。
推荐调试步骤
-
打印当前类路径:
System.out.println(System.getProperty("java.class.path"));
-
查看目标类是否存在:
javap -classpath your.jar com.example.MyClass
-
使用 IDE 查看类是否被正确加载。
四、总结
问题 | 解决方法 |
---|---|
类不存在于 classpath | 添加对应的 jar 包或模块依赖 |
包名或类名不一致 | 确保两端类名、包名完全一致 |
未注册 Schema | 使用 RuntimeSchema.getSchema(clazz) 获取 schema |
热加载/OSGi 环境 | 调试类加载器或禁用相关插件 |
Protostuff lite 模式 | 改为完整版或检查使用方式 |
如果你能提供具体的代码片段或调用方式,我可以帮你更精准地定位问题。例如:
- 是如何调用序列化/反序列化方法的?
- 使用的是哪种 Protostuff 模式?(lite / full / linked / etc.)
- 是本地反序列化还是跨服务传输?(如 RPC)
好了,今天分享到这里。希望你喜欢这次的探索之旅!不要忘记 "点赞" 和 "关注" 哦,我们下次见!🎈
本文完结!
祝各位大佬和小伙伴身体健康,万事如意,发财暴富,扫下方二维码与我一起交流!!!