2

I want to run a cron in java which will run every 'x' hrs daily. X will be decided by a value in the database which is not static. I tried something like this:

private static String cronRunTime = getCronRunTimeFromDb();
private String cronExpression = "* " + cronRunTime + " * * *";

But the main problem I am facing is I am not getting how can I configure this value in the @Scheduled annotation.

I tried something:

@Scheduled(cron = cronExpression)
    public void myCron(){

    }

But I am getting an error during compilation:

error: element value must be a constant expression
    @Scheduled(cron = cronExpression)

Can someone please help me in solving this issue.

the_unknown_spirit
  • 2,518
  • 7
  • 34
  • 56
  • Is your question about "why do I get a compiler error?" or it is more about "how do I configure cron expression scheduled task based on information from database?" – Vladimir L. Jul 18 '17 at 21:20
  • my question is "how do I configure cron expression scheduled task based on information from database" – the_unknown_spirit Jul 19 '17 at 05:56
  • I provided 2 options in my answer below: using Java code and configure task programmatically (using Spring), and declarative way using `@Scheduled` annotation and placeholder capabilities of Spring. You may also drop the Spring way and simply use pure JDK capabilities to run scheduled tasks: `ExecutorService`, etc. – Vladimir L. Jul 19 '17 at 08:18

2 Answers2

1

"sec min hour day month weekday"

"0 0 * ? * *" is the cron expression for every hour every day.
"0 0 10 ? * *" is the cron expression for 10am every day.

What you're looking for with every "x" hours every day would be:

"0 0 */x ? * *"

Hope that helps.

Michael Conard
  • 709
  • 5
  • 10
1

According to Java specification values of annotation elements for primitive types and String must be constant expressions - something that can be evaluated at compile time, not at runtime.

In short: you cannot pass to an annotation attribute the value that is evaluated at runtime (fetched from database, read from property file, or even returned from a static function like System.currentTimeMillis())

If you have a dynamic logic for your scheduled task that depends on some kind of configuration (in database or property file), you should consider using ScheduledTaskRegistrar and its addCronTask(CronTask task) method, which is of course not as neat as simple annotation.

See example on how to use ScheduledTaskRegistrar among responses here:

As an alternative you can use a property placeholder logic to populate cron attribute of @Scheduled annotation as it is described already in other questions:

You can even make Spring to read properties from database if you really gonna go wild, see:

Vladimir L.
  • 1,116
  • 14
  • 23