Couldn‘t store trigger ‘‘ for ‘‘ job:Couldn‘t retrieve job because the BLOB couldn‘t be deserialized

解决方法在最下面,可以直接跳过前面解析部分。

具体错误日志如下:

org.quartz.JobPersistenceException: Couldn't store trigger 'Axxxx' for 'Bxxxx' job:Couldn't retrieve job because the BLOB couldn't be deserialized: com.demo.TaskClass; local class incompatible: stream classdesc serialVersionUID = 4545949010006210417, local class serialVersionUID = -7472559171496155799
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1228)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.doUpdateOfMisfiredTrigger(JobStoreSupport.java:1042)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:991)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3264)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:4012)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:4033)
Caused by: org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: com.demo.TaskClass; local class incompatible: stream classdesc serialVersionUID = 4545949010006210417, local class serialVersionUID = -7472559171496155799
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1397)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1210)
	... 5 common frames omitted
Caused by: java.io.InvalidClassException: com.demo.TaskClass; local class incompatible: stream classdesc serialVersionUID = 4545949010006210417, local class serialVersionUID = -7472559171496155799
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2003)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1850)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2160)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:503)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:461)
	at java.util.HashSet.readObject(HashSet.java:341)
	at sun.reflect.GeneratedMethodAccessor1011.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1184)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2296)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2187)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2405)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2329)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2187)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:503)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:461)
	at java.util.HashMap.readObject(HashMap.java:1412)
	at sun.reflect.GeneratedMethodAccessor486.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1184)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2296)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2187)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2405)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2329)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2187)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1667)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:503)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:461)
	at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.getObjectFromBlob(StdJDBCDelegate.java:3201)
	at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:860)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1390)
	... 6 common frames omitted

1、这个错误真的把我搞得头疼,一开始不太明白错误的点在哪,一直在搜索"Couldn't retrieve job because the BLOB couldn't be deserialized"这个关键错误,网上有关于这个错误的解决方案,可以参考https://www.yepk.cn/archives/quartz-error.html​​​​​​

 2、经过方案的查阅也了解到了是由于任务实体类com.demo.TaskClass被改了,导致了定时器不认识这个类之前的样子了

3、主要错误日志其实是这里:local class incompatible: stream classdesc serialVersionUID = 12345, local class serialVersionUID = 6789。错误复现步骤,一开始创建一个A定时任务,定时任务正常工作,然后改一下实体类TaskClass的数据结构,比如加个属性,启动服务后就会报这个错,这是因为没有自定义序列化serialVersionUID。

4、创建定时任务实体类要实现Serizlizable接口,这时候启动服务这个类会被分配一个序列化ID也就是serialVersionUID,如果没有自定义序列化ID,那么系统就会给这个类自动生成一个序列化ID,这个序列化ID是根据这个类的hash值生成的,所以修改实体类数据结构后,hash值会变,序列化ID也就变了,就像第三个步骤里由12345变成了6789,导致了定时器去反序列化的时候会去找6789,但是找到了老任务A时,A的序列化ID是12345,定时器就不认识了,就没办法反序列化,就会报错。

5、解决方案:给实体类自定义序列化ID为老的12345即可。

6、代码展示:

//实体类 此时序列化ID是12345
public  class TaskClass implements Serializable {

    private String name;

}
//修改实体类数据结构 此时序列化ID会变成6789
public  class TaskClass implements Serializable {

    private String name;

    private String age;

}
//解决方法 自定义序列化ID为12345,这时这个类的序列化ID就不会因为改变结构而变化了 因为被写死了

public  class TaskClass implements Serializable {

    private static final long serialVersionUID = 12345L;

    private String name;

    private String age;

}

7、关于序列化ID自动生成,因为我们一般也不会自己去定义序列化ID,毕竟自己可能会定义到一个重复的,IDEA有自动生成序列化ID的快捷方式,保证会根据类的HASH值生成序列化ID,这样就不会重复了,操作步骤如下:

进入IDEA->File->setting->Editor->inspections,然后搜索serialVersionUID,勾选以下两个选项,然后Apply

 光标放在类名下面,按Alt+Enter 创建UID即可

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值