2
votes

I am using Spring MVC and I am trying to write a scheduled task that runs every hour. The catch is that when the application starts up, it should calculate the duration until the next hour and use that value as a initial delay. This way, the scheduled task can run at exact hours like 1pm...2pm...3pm etc.

In my code below, I tried to calculate the initial delay inside of a @PostConstruct annotation. However, when I try to use the variable inside of a @Scheduled annotation, I get the following error message: The value for annotation attribute Scheduled.initialDelay must be a constant expression

private LocalDateTime now;
private  long delayUntilNextHour;
private long delayUntilNextDay;

@PostConstruct
public void initialize(){

    now = LocalDateTime.now();
    LocalDateTime nextHour = now.plusHours(1).withMinute(0).withSecond(0).withNano(0);
    delayUntilNextHour = now.until(nextHour, ChronoUnit.MILLIS);


}


@Scheduled(initialDelay= delayUntilNextHour, fixedRate=3600000) //Runs every hour
public void test(){
    //ADD LOGIC 
    hourMap.clear();
}

I cannot insert "delayUntilNextHour" into the initialDelay parameter of @Scheduled. I was wondering if anyone can point me in the right direction in how to get around this.

I have tried to make delayUntilNextHour a static final (constant), but it still does not work. I have also tried the string variant "initialDelayString", but that does not work either.

1
use a fancy cron expression to run "at the hour" (most likely "0 0 * * * *", see docs.spring.io/spring/docs/current/javadoc-api/org/…) - user180100
ah that works thanks so much! - Solace

1 Answers

2
votes

Use System.setProperty("delayUntilNextDay", delayUntilNextHour.toString()); inside the initialize() method and use @Value("${delayUntilNextDay}") to access the value

@Scheduled(initialDelay= @Value("${delayUntilNextDay}"), fixedRate=3600000) //Runs every hour
public void test(){
    //ADD LOGIC 
    hourMap.clear();
}

I haven't tried the above code.