2013-08-06 9 views
7

Ok così qui è che voglio pianificare un'attività per eseguire l'ultimo giorno di ogni mese sull'espressione cron 10:10 AM.My èSoluzione alternativa per CronSequenceGenerator L'ultimo giorno del mese?

0 10 10 L * ? 

Ora il problema è CronSequenceGenerator sta gettando NumberFormatException per 'L' value.Questo significa che il CronSequenceGenerator di Spring non supporta questo tipo di espressione. Come fare in un altro modo (soluzione alternativa). Non voglio usare il quarzo o Spring lo sosterrà nelle nuove versioni.

Qui è pieno 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) 

Aggiornamento:

segue è il mio metodo di pianificazione

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

E sulla linea 2 getta NumberFormatException quando passo specificato espressione cron.

+0

ho guardato un po 'intorno, e sembra che L è effettivamente supportato. Come stai definendo il lavoro? Annotazione? Probabilmente dovresti aggiungere questo alla tua domanda. – Magnilex

+0

@Magnilex verifica aggiornamento –

+0

Grande. Potresti anche incollare il codice rilevante che chiama il metodo 'start()'? Mi dispiace per questo, ma penso davvero che usare 'L' dovrebbe funzionare. – Magnilex

risposta

6

Questa caratteristica non è in standard cron expression syntax. Quindi probabilmente Spring non lo realizzerà mai. Guardando il code, non riesco a vedere nessuna soluzione chirurgica estendendo CronSequenceGenerator. Allora perché non usi Quartz visto che è un particular feature?

In base all'esigenza specifica, è possibile implementare il proprio Trigger. Qualcosa di simile:

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

Grazie, E non potrei usare il quarzo perché richiede un refactoring a livello di architettura ... "Mi uccideranno" .... E proverò con te Idea CustomTrigger Sembra che funzionerà ... –

5

Come una soluzione che sarebbe pianificare l'esecuzione di tutte le date

0 10 10 * * ? 

e controllato la data effettiva nel metodo previsto

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

Funzionerebbe, ma pianificherei il metodo solo per gli ultimi giorni del mese, come il giorno 27-31. – Magnilex

+0

Sì, penso che sarebbe un po 'di ottimizzazione –

+0

Grazie ... Ma funzionerà solo per l'ultimo giorno del mese. –

2

versione ottimizzata, che gira solo l'ultimo giorno di un mese:

@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 
    } 
} 
Problemi correlati