2013-08-06 26 views
7

好了,所以這裏是我想安排一個任務在10:10 AM.My cron表達式在每月的最後一天運行時CronSequenceGenerator的解決方法月份的最後一天?

0 10 10 L * ? 

現在的問題是CronSequenceGenerator拋出了NumberFormatException的「L」值。這意味着Spring的CronSequenceGenerator不支持這種表達。如何以任何其他方式來做到這一點(解決方法)。我不想使用石英或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

我四處張望了一下,似乎使L和實際支持。你如何定義這份工作?註解?你應該添加這個到你的問題。 – Magnilex

+0

@Magnilex檢查更新 –

+0

太好了。你還可以粘貼調用'start()'方法的相關代碼嗎?我很抱歉,但我真的認爲使用'L'應該可以。 – Magnilex

回答

6

此功能在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(); 
    } 
} 
+0

謝謝,我不能使用石英,因爲它要求架構級重構...「他們會殺了我」....我會嘗試你的CustomTrigger的想法它似乎會工作... –

5

作爲一種變通方法我會安排執行所有日期

0 10 10 * * ? 

,並在預定方法檢查的實際日期

public void scheduledTask() { 
    Calendar c = Calendar.getInstance(); 
    if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) { 
     ... 
    } 
} 
+2

它會工作,但我只會安排該方法的可能最後幾天,像27-31天。 – Magnilex

+0

是的,我認爲這將是一些優化 –

+0

謝謝......但它只會在月的最後一天工作。 –

2

優化版本,僅在每月的最後一天運行:

@Scheduled(cron = "0 55 23 28-31 * ?") 
public void doStuffOnLastDayOfMonth() { 
    final Calendar c = Calendar.getInstance(); 
    if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) { 
     // do your stuff 
    } 
} 
相關問題