发现一个nutz-integration-quartz的小问题,就不在github上面提了,在论坛写出来吧。
新建一个Trigger的时候,简单的定时任务如下:
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger5_1", "tGroup5")
.startAt(DateBuilder.futureDate(10, IntervalUnit.SECOND))
.forJob(jobDetail)
.build();
如果没有调用 .withSchedule()方法的话,会在创建的时候报如下错误:
java.lang.RuntimeException: org.quartz.SchedulerException: Repeat Interval cannot be zero.
at org.nutz.lang.Lang.wrapThrow(Lang.java:184)
at org.nutz.integration.quartz.QuartzManagerImpl.add(QuartzManagerImpl.java:142)
at com.xiaomo.main.module.QuartzModule.add(QuartzModule.java:60)
然后一步步调试进去,发现是这样的,在org.nutz.integration.quartz.Quartzs中方法makeSimpleTrigger(String jobName, String jobGroup, int fixedRate, int count, long initialDelay)中
public static SimpleTrigger makeSimpleTrigger(String jobName, String jobGroup, int fixedRate, int count, long initialDelay) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.simpleSchedule();
if (fixedRate > 0)
schedule.withIntervalInSeconds(fixedRate);
if (count > 0) {
schedule.withRepeatCount(count);
} else {
schedule.repeatForever();
}
TriggerBuilder<SimpleTrigger> trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).withSchedule(schedule);
if (initialDelay > 0)
trigger.startAt(new Date(System.currentTimeMillis() + initialDelay*1000));
return trigger.build();
}
如果 count > 0 ,才注入repeatCount,否则就设置为 -1(SimpleTrigger.REPEAT_INDEFINITELY) ,由于默认值就是 0 ,所以就会导致把repeatCount设置为 -1,而此时repeatInterval 取了默认值 0 ,所以此时
repeatCount = -1
repeatInterval = 0
之后,在org.quartz.core.QuartzScheduler的方法public void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) throws SchedulerException中,会调用 opt.validate(),来核验 repeat值的合法性,方法是org.quartz.impl.triggers.SimpleTriggerImpl中的validate()
@Override
public void validate() throws SchedulerException {
super.validate();
if (repeatCount != 0 && repeatInterval < 1) {
throw new SchedulerException("Repeat Interval cannot be zero.");
}
}
此时就会抛出上述异常。其实 这个 (repeatCount != 0 && repeatInterval < 1) 的意思就是,这个任务会在未来隔repeatInterval时间来执行repeatCount次,(注,第一次不算在repeatCount中的),所以就相当于未来执行无限次但是间隔时间为0,任务就无法执行,就抛出异常了。
解决方法:
在创建Trigger的时候,增加一个.withSchedule()方法,如下:
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger5_1", "tGroup5") .withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)
.withRepeatCount(0)
)
.startAt(DateBuilder.futureDate(10, IntervalUnit.SECOND))
.forJob(jobDetail)
.build();
或者把nutz-integration-quartz的源码中org.nutz.integration.quartz.Quartzs中方法makeSimpleTrigger改一下,把count > 0 改成 count >= 0 就可以了。
我这边使用的nutz-integration-quartz是1.r.65的,quartz版本是2.2.3的。
找了这个问题一个下午,总算解决了,分享出来,大家不会再踩同样的坑了。