java类型强转,自己不能转换成自己

java类型强转,自己不能转换成自己

产生背景

使用SpringBoot 集成Quartz框架,项目启动时报错:

2020-08-12 13:49:13.003 ERROR 8512 --- [eduler_Worker-3] org.quartz.core.JobRunShell              : Job test-group.test threw an unhandled Exception: 

java.lang.ClassCastException: cn.bupt.zcc.dynamicquartz.model.ScheduleJob cannot be cast to cn.bupt.zcc.dynamicquartz.model.ScheduleJob

我眯着眼睛瞅了几遍,并在项目中进行全局搜索,确定类限定名是完全一致!一时想不出啥原因,于是寻求度娘帮助,找到了这篇博文,参考链接: link.
Java 中,判断两个类型是否相同需要:1.两个类有相同的限定名;2.两个类由同一类加载器实例加载。既然类限定名是没有问题的,那么只能说明要强转成的 TypeA 和从 memcached 中取回的 TypeA(Java 标准反序列化生成的实例的 class)不是由同一类加载器实例加载的。后来查了一下,果不其然,同事写的那段逻辑是用 spring-devtool 启动的,而 spring-devtool 自己实现了一个类加载器,这个类加载器默认加载所有自己写的 Java 代码编译出来的 .class (也就是非 .jar 中的 .class),加载要强转为的 TypeA 就是由他加载的。而 memcached 中取回 TypeA 这块的逻辑是在 .jar 中封包的,这部分是由 AppClassLoader 加载的。这样就造成了同样是 TypeA,由不同类加载器实例(别提实例了,类加载器的类都不同)加载出来的情况,因此,他们虽然名字一样,但是已经不是一个类了,所以不能强转成功了。
发生错误时的代码:

package cn.bupt.zcc.dynamicquartz.job;

import cn.bupt.zcc.dynamicquartz.model.ScheduleJob;
import cn.bupt.zcc.dynamicquartz.service.QuartzService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

/**
 *
 *
 * @author: Even
 * @create: 
 **/
@Service("quartzJobFactory")
public class QuartzJobFactory extends QuartzJobBean {

    @Autowired
    QuartzService quartzService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
      //  ScheduleJob object = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
        /**
         * 自己不能强转成自己我是没想到的
         */
        ScheduleJob object = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
        if(object.getMethodName()==null || object.getMethodName().equals("")){
            quartzService.executeTask(object.getBeanName());
        }else {
            quartzService.executeTask(object.getBeanName(),object.getMethodName());
        }
    }
}

jobExecutionContext.getMergedJobDataMap().get(“scheduleJob”);得到PostgreSQL数据库bytea的job_data字段反序列化出来的对象和SpringBoot devtools 加载的ScheduleJob 不是同一个类的实例

解决方法

不使用Springboot devtools,将其在pom.xml中注释掉

<!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>-->

重启项目,不再报ClassCastException了

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值