2013-08-06 51 views
7

Ok như vậy ở đây nó là tôi muốn sắp xếp một nhiệm vụ để chạy vào ngày cuối cùng của mỗi tháng trên biểu cron 10:10 AM.My đượcGiải pháp cho CronSequenceGenerator Ngày cuối cùng của tháng?

0 10 10 L * ? 

Bây giờ vấn đề là CronSequenceGenerator được ném NumberFormatException cho 'L' value.Điều này có nghĩa là CronSequenceGenerator của Spring không hỗ trợ kiểu biểu thức này. Làm thế nào để thực hiện điều này theo bất kỳ cách nào khác (workaround). Tôi không muốn sử dụng quartz hoặc Spring có hỗ trợ điều này trong các bản phát hành mới hay không.

Dưới đây là toàn stacktrace:

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) 

Cập nhật:

Sau đây là phương pháp lập kế hoạch của tôi

/** 
    * 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; 
    } 

Và trên dòng 2 nó ném NumberFormatException khi tôi vượt qua quy định biểu hiện cron.

+0

Tôi nhìn xung quanh một chút, và có vẻ như rằng L là thực sự được hỗ trợ. Bạn định nghĩa công việc như thế nào? Chú thích? Bạn có lẽ nên thêm điều này vào câu hỏi của bạn. – Magnilex

+0

@Magnilex kiểm tra cập nhật –

+0

Tuyệt vời. Bạn cũng có thể dán mã có liên quan gọi phương thức 'start()' không? Tôi xin lỗi về điều này, nhưng tôi thực sự nghĩ rằng việc sử dụng 'L' sẽ hoạt động. – Magnilex

Trả lời

6

Tính năng này không có trong standard cron expression syntax. Vì vậy, có lẽ mùa xuân sẽ không bao giờ thực hiện nó. Nhìn vào số code, tôi không thể thấy bất kỳ giải pháp nào phẫu thuật mở rộng CronSequenceGenerator. Vậy tại sao bạn không sử dụng Quartz vì nó là particular feature?

Tùy thuộc vào nhu cầu chính xác của bạn, bạn có thể triển khai Trigger của riêng mình. Một cái gì đó như:

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

Cảm ơn, Và tôi could'nt sử dụng thạch anh bởi vì nó đòi hỏi cấu trúc cấp refactoring ... "Họ sẽ giết tôi" .... Và tôi sẽ cố gắng của bạn Ý tưởng của CustomTrigger Có vẻ như nó sẽ hoạt động ... –

5

Là một workaround tôi sẽ lên kế hoạch thực hiện cho tất cả các ngày

0 10 10 * * ? 

và kiểm tra ngày thực tế trong phương pháp dự kiến ​​

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

Nó sẽ hoạt động, nhưng tôi sẽ chỉ lên lịch phương thức cho những ngày cuối tháng có thể, một cái gì đó như ngày 27-31. – Magnilex

+0

Vâng, tôi nghĩ rằng nó sẽ là một số tối ưu hóa –

+0

Cảm ơn ... Nhưng nó sẽ chỉ hoạt động cho ngày cuối cùng của tháng. –

2

phiên bản tối ưu mà chỉ chạy vào ngày cuối cùng của một tháng:

@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 
    } 
} 
Các vấn đề liên quan