好的,所以我想安排一个任务在每个月的最后一天上午10:10运行。我的cron表达是
0 10 10 L * ?
现在问题是CronSequenceGenerator正在为'L'值抛出NumberFormatException。这意味着Spring的CronSequenceGenerator不支持这种表达式。如何以任何其他方式执行此操作(解决方法)。我不这样做想要使用quartz或者spring会在新版本中支持它。
这是完整的堆栈跟踪:
Exception in thread "main" java.lang.NumberFormatException: For input string: "L"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at org.springframework.scheduling.support.CronSequenceGenerator.getRange(CronSequenceGenerator.java:324)
at org.springframework.scheduling.support.CronSequenceGenerator.setNumberHits(CronSequenceGenerator.java:297)
at org.springframework.scheduling.support.CronSequenceGenerator.setDays(CronSequenceGenerator.java:275)
at org.springframework.scheduling.support.CronSequenceGenerator.setDaysOfMonth(CronSequenceGenerator.java:266)
at org.springframework.scheduling.support.CronSequenceGenerator.parse(CronSequenceGenerator.java:239)
at org.springframework.scheduling.support.CronSequenceGenerator.<init>(CronSequenceGenerator.java:81)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:54)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:44)
at com.hcdc.coedp.datantar.scheduler.SchedulerUtil.start(SchedulerUtil.java:75)
at com.hcdc.coedp.datantar.scheduler.SchedulerUtil.changeTrigger(SchedulerUtil.java:106)
at com.hcdc.coedp.datantar.scheduler.SchedulingService.scheduleTransfer(SchedulingService.java:70)
at com.hcdc.coedp.datantar.scheduler.Scheduler.schedule(Scheduler.java:107)
at main.Main.main(Main.java:47)
更新
以下是我的安排方法
/**
* Schedule a task {@link Task} with a specified cron expression.
* @param task {@link Task}
* @param cronExpression cron expression to be applied must be a vaild one.
* @param taskName
* @return
*/
public String start(Task task, String cronExpression, String taskName) {
CronTrigger trigger = new CronTrigger(cronExpression);//line 2
CronSequenceGenerator generator = new CronSequenceGenerator(cronExpression, TimeZone.getTimeZone("GMT+5:30"));
List<Date> dateList = new ArrayList<>(5);
Date currentDate = new Date();
for (int i = 0; i < 5; i++) {
currentDate = generator.next(currentDate);
dateList.add((currentDate));
System.out.println("Next Exceution times are" + currentDate);
}
ScheduledFuture sf = tps.schedule(task, trigger);
//TODO Save this scheduled future with a specific task name.
ContextHolder.schduledFutureMap.put(taskName, sf);
return cronExpression;
}
在第2行,当我传递指定的cron表达式时,它会抛出NumberFormatException。
答案 0 :(得分:8)
此功能不在standard cron expression syntax中。所以Spring可能永远不会实现它。查看code,我看不到任何扩展CronSequenceGenerator
的外科解决方案。那你为什么不使用Quartz,因为它是particular feature?
根据您的具体需要,您可以实施自己的Trigger。类似的东西:
import java.util.Date;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
public class LastDayOfMonthTrigger implements Trigger {
private final LocalTime time;
public LastDayOfMonthTrigger(LocalTime time) {
this.time = time;
}
@Override
public Date nextExecutionTime(TriggerContext ctx) {
Date last = ctx.lastScheduledExecutionTime();
LocalDate date = last == null ? new LocalDate() : new LocalDate(last).plusDays(1);
LocalDate lastDay = date.dayOfMonth().withMaximumValue();
return lastDay.toDateTime(time).toDate();
}
}
答案 1 :(得分:6)
作为一种解决方法,我会安排所有日期的执行
0 10 10 * * ?
并检查计划方法中的实际日期
public void scheduledTask() {
Calendar c = Calendar.getInstance();
if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) {
...
}
}
答案 2 :(得分:0)
还有另一种解决方法:
生成一个月的数据。该程序应在下个月的第一天运行,以确保捕获整个月的所有数据。
import org.apache.commons.lang3.time.DateUtils;
@Scheduled(cron = "0 0 0 1 * ?") // runs on the first day of each month
public void doStuffOnFirstDayOfMonth() {
Date now = DateUtils.addDays(new Date(), -1); // "now" is now on the last day of the month
}