springboot集成quartz出错,记录追源码过程!

背景

最近在做一个项目,需要使用定时任务,打算直接用我以前搭的springboot集成quartz的demo,地址:https://gitee.com/zhanpg/springboot-quartz,结果一直报错。

错误提示

java.lang.IllegalStateException: Active Scheduler of name ‘OneknowClusteredScheduler’ already registered in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!

找bug

  • 开始网上搜索这种错误,发现根本没有,没办法,只能靠自己了。
  • 错误里提示‘OneknowClusteredScheduler’已经存在,这个是我在quartz配置文件里配的scheduler实例名,那就从这个开始入手。
  • 首先找出这个错误提示在源码的哪个地方
try {
           SchedulerRepository repository = SchedulerRepository.getInstance();
           synchronized(repository) {
               Scheduler existingScheduler = schedulerName != null ? repository.lookup(schedulerName) : null;
               Scheduler newScheduler = schedulerFactory.getScheduler();
               if (newScheduler == existingScheduler) {
                   throw new IllegalStateException("Active Scheduler of name '" + schedulerName + "' already registered in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!");
               }

               if (!this.exposeSchedulerInRepository) {
                   SchedulerRepository.getInstance().remove(newScheduler.getSchedulerName());
               }

               var10 = newScheduler;
           }
       } finally {
           if (overrideClassLoader) {
               currentThread.setContextClassLoader(threadContextClassLoader);
           }
       }

当newScheduler和existingScheduler相同时,就会报这个错,debug到这里
在这里插入图片描述
两个确实相同;接着找原因,
Scheduler existingScheduler = schedulerName != null ? repository.lookup(schedulerName) : null;
这里提示schedulerName=OneknowClusteredScheduler,所以existingScheduler=repository.lookup(schedulerName);对比原来项目,debug到这里,发现schedulerName=SchedulerFactory;应该就是这个schedulerName的问题了;schedulerName是这个类SchedulerFactoryBean的属性;在QuartzConfig中有定义这个bean:

@Bean("SchedulerFactory")
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setQuartzProperties(quartzProperties());
        return factory;
    }

应该是初始化这个bean的时候设置了这个值,
这个方法中,首先调用afterPropertiesSet()这个方法,此方法中又调用prepareSchedulerFactory(),里面又调用initSchedulerFactory方法,此时schedulerName还是null,这个方法中最后

if (this.schedulerName != null) {
            mergedProps.setProperty("org.quartz.scheduler.instanceName", this.schedulerName);
        } else {
            String nameProp = mergedProps.getProperty("org.quartz.scheduler.instanceName");
            if (nameProp != null) {
                this.schedulerName = nameProp;
            } else if (this.beanName != null) {
                mergedProps.setProperty("org.quartz.scheduler.instanceName", this.beanName);
                this.schedulerName = this.beanName;
            }
        }

当schedulerName=null时,schedulerName取得是配置文件中instanceName,就是OneknowClusteredScheduler,看着没毛病,接着去原来项目中debug到这里,重大发现,原来项目中此处得代码

if (this.schedulerName != null) {
           mergedProps.setProperty("org.quartz.scheduler.instanceName", this.schedulerName);
       }

就这么多,没了。事情还没结束,原来项目到这里schedulerName是有值的,为啥现在项目到这里schedulerName是null呢,继续找问题,最后发现在项目中

	//现在项目
	public void setBeanName(String name) {
        this.beanName = name;
    }
    //原来项目
    public void setBeanName(String name) {
        if (this.schedulerName == null) {
            this.schedulerName = name;
        }

    }

在给beanName赋值时,原项目已经给schedulerName赋值了,但是现在项目中没有,问题终于找到了。

解决bug

现在项目和原来项目的springboot版本不一致,由于引的quartz包是直接用spring-boot-starter-quartz,这就导致了quartz版本也不一样,解决这个问题,只能换springboot版本了,或者单独引quartz的包。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值