This is the error message I was getting when I was trying to setup a job (scheduled task) that would send emails every 45 minutes in my document sharing app. In this post, I won’t be delving into details of what the job was, but rather focus on the error ‘Cron expression must consist of 6 fields (found 5 in */45 * * * *)’ and why you may see it. The error that you see is to do with how you define the cron job like expressions for the Spring scheduled tasks vs those for Cron jobs on unix.
Cron expression must consist of 6 fields
When I was defining the schedule for the email job in the Document Sharing App (https://documents.mydayto-do.com), I wanted it to run every 45 minutes. Knowing what I know about cron expressions from unix and how to setup scheduled tasks in Spring, I defined it as follows,
@Async
@Scheduled(cron = "*/45 * * * *")
public void sendScheduledEmails() {
List<Schedule> toBeSent = new ArrayList<>();
String currentRange = DateTimeService.getTimeWindow();
log.info("About to get schedules for current hour {} ", currentRange);
scheduleRepository.findAll().forEach(schedule -> {
if(schedule.getTimeWindow().equalsIgnoreCase(currentRange)
&& !schedule.getIsSent()) {
toBeSent.add(schedule);
}
});
log.info("About to trigger async job to send emails");
scheduleAsyncJob(toBeSent);
}
Only to be greeted by the error
Encountered invalid @Scheduled method 'sendScheduledEmails': Cron expression must consist of 6 fields (found 5 in "*/45 * * * *")
On doing a simple online search for this error yielded the right results.
Spring granularity
You see, in Spring framework when you define a schedule you start it by the second as opposed to starting it by the minute in Unix based cron expressions.
* | * | * | * | * |
Minute | Hour | Day of month | Month | Day of week |
* | * | * | * | * | * |
Seconds | Minute | Hour | Day of month | Month | Day of week |
As you can see above, a Spring scheduled tasks just has one extra parameter which is to define the seconds from (0-59) for the scheduled task. Hence the schedule definition for the Spring scheduled task is just a bit more granular than that of a unix Cron job. Therefore, in this instance to solve my problem, all I had to do was simply redefine the schedule and add another ‘*’ for the seconds,
@Scheduled(cron = "* */45 * * * *")
public void sendScheduledEmails() {
....
}
And that was it. Problem solved!
Summary
You can check out the full source code for the Document Sharing App (named File Sharing App for now) on Github, file-sharing-app.
If you find any of my posts useful and want to support me, you can buy me a coffee 🙂
https://www.buymeacoffee.com/bhumansoni
Here are some of my other bloposts on Java and Spring,
How to build a blog engine with React & Spring Boot – Part 1 – My Day To-Do (mydaytodo.com)
How to build a jokes client in Java Spring Boot with RestTemplate – My Day To-Do (mydaytodo.com)
Upload to AWS S3 bucket from Java Spring Boot app – My Day To-Do (mydaytodo.com)
How to deploy spring boot app to AWS & serve via https – My Day To-Do (mydaytodo.com)
0 Comments