14

I have a Spring scheduled method that is periodically run:

@Scheduled(cron = "${spring.cron.expression}")
public void demonJob() { ... }

The cron expression is successfully read from the application.properties:

spring.cron.expression=0 0 * * * *

Now, I want to deploy my application to a special environment on which this particular scheduled method is not supposed to run. If I leave the cron property empty like this...

spring.cron.expression=

... I get the following exception:

Encountered invalid @Scheduled method 'demonJob': Cron expression must consist of 6 fields (found 0 in "")

How can I disable the Scheduled method elegantly, ideally only by providing a different setting in application.properties?

M. Justin
  • 14,487
  • 7
  • 91
  • 130
Fritz Duchardt
  • 11,026
  • 4
  • 41
  • 60
  • If you ever want to go this way, this topic is about "never executing cron expressions" : http://stackoverflow.com/questions/13835221/quartz-cron-expression-that-will-never-execute – Arnaud Jan 22 '16 at 09:49
  • @Berger but that question deals with quartz cron expressions which seem more flexible than spring cron expressions. – Fritz Duchardt Jan 22 '16 at 09:51

4 Answers4

11

As of Spring 5.1.0, the special cron value "-" can be used with the @Scheduled annotation to disable the cron trigger.

The special value "-" indicates a disabled cron trigger, primarily meant for externally specified values resolved by a ${...} placeholder.

For your specific example, you merely need to set the spring.cron.expression variable to this value. If this is a Spring Boot project, you can use one of the many externalized configuration options available for this purpose, including:

  • Command line argument
  • Java System property
  • OS environment variable
  • Profile-specific application property for a profile used specifically for that environment

If this is not a Spring Boot project, you can still specify this property, though the mechanism to do so is going to be less standard and more project specific.

M. Justin
  • 14,487
  • 7
  • 91
  • 130
8

Empty string is an incorrect cron expression. If you want to disable scheduler in particular condition just use @Profile annotation or if you have to operate on property use @ConditionalOnProperty annotation from Spring Boot.

@Component
@ConditionalOnProperty(prefix = "spring.cron", name = "expression")
public class MyScheduler {
   @Scheduled(cron = "${spring.cron.expression}")
   public void demonJob() throws .. { .. }
}
Jakub Kubrynski
  • 13,724
  • 6
  • 60
  • 85
  • ConditionalOnProperty seems like a cool solution - unfortunately this is not a Spring Boot Project. The Profile solution would require that we add all profiles that want the scheduler, but we much rather would disable it only for one specific profile. – Fritz Duchardt Jan 22 '16 at 09:58
  • You can very simply implement @ConditionalOnProperty on your own. It's Conditional class with 5 lines – Jakub Kubrynski Jan 22 '16 at 10:01
1

I could give another approach. Just redefine applicatino cron expression in any way to set unreachable time period. E.g. spring.cron.expression=1 1 1 1 1 ? (this is I use in my code and it is enough for me).

Profit of this approach is that you do not have to do any additional changes in the code.

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • 3
    Isn't your example to be executed Jan 1st at 1:01:01? That doesn't look like "never". Or do you assume to change the schedule right before that date to avoid execution? Could you please explain in more details? – Yoory N. Nov 17 '17 at 13:49
  • You're right. I just wanted to set unreachable scheduler. This expression works for my code (yes, I think it will be run one once per year). But I wanted to give an approach to solve this problem (you could set one time moment in two years e.g.) – Oleg Cherednik Nov 17 '17 at 13:52
0

Possible Solution to your Question

  1. Configure your properties file based on the environment
  2. Configure your ApplicationContext according to your environment profile.
  3. Use Environment Specific CRON Entries.
  4. Please check this link which may help you.
Praveen Kumar K S
  • 3,024
  • 1
  • 24
  • 31