19

How to customize the exception handling for @Scheduled annotation from spring ?

I have Cron jobs which will be triggered in the server (Tomcat 6) and when any exceptions occur I need to do some handling.

  • Spring version 3.2
  • Tomcat Server 6
Clijsters
  • 4,031
  • 1
  • 27
  • 37
user3515080
  • 545
  • 2
  • 6
  • 17
  • What do you mean by customized exception handling? Can't you just handle any exception inside the `@Scheduled` method? – geoand Jun 04 '14 at 08:26
  • @geoand, yes i can. but i need to log the information about the job for the both cases like fail or success. is there any generic way to do that ? – user3515080 Jun 04 '14 at 08:48
  • Depending on your needs, Spring AOP might be worth looking into – geoand Jun 04 '14 at 09:24
  • @geoand, if you any example can you explain me here ? thank you. – user3515080 Jun 04 '14 at 09:32
  • If you need to do some stuff before all @Scheduled method, you should check out Spring AOP.http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html – geoand Jun 04 '14 at 09:34

3 Answers3

27

If you want to use Java Config you will need to create configuration implementing SchedulingConfigurer

@EnableScheduling
@Configuration
class SchedulingConfiguration implements SchedulingConfigurer {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final ThreadPoolTaskScheduler taskScheduler;

    SchedulingConfiguration() {
        taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setErrorHandler(t -> logger.error("Exception in @Scheduled task. ", t));
        taskScheduler.setThreadNamePrefix("@scheduled-");

        taskScheduler.initialize();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskScheduler);
    }
}

You can modify error handler for your needs. Here I only log a message.

Don't forget to call taskScheduler.initialize();. Without it you'll get:

java.lang.IllegalStateException: ThreadPoolTaskScheduler not initialized
Mariusz.v7
  • 2,322
  • 2
  • 16
  • 24
5

You could implement and register an ErrorHandler for the ThreadPoolTaskScheduler that is used for your scheduling annotations.

 <task:annotation-driven scheduler="yourThreadPoolTaskScheduler"  />

 <bean id="yourThreadPoolTaskScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
        <property name="poolSize" value="5" />
        <property name="errorHandler" ref="yourScheduledTaskErrorHandler" />
 </bean>

 <bean id="yourScheduledTaskErrorHandler" 
     class="com.example.YourScheduledTaskErrorHandler"/>
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • One note: if you have ``, the lines above **replace** it. You replace your Task Scheduler with this Task:Annotation Driven + 2 beans. Afterwards, change your `` to point to this new scheduler name. – gene b. Nov 16 '22 at 00:30
  • See: https://stackoverflow.com/a/74453809/1005607 – gene b. Nov 19 '22 at 15:49
4

Why not wrap your business logic and do a simple try catch in your @schedule method. Then you can log or take whatever action is necessary for failure cases.

@Scheduled(cron = "${schedulerRate}")
public void scheduledJob() {
    try {
        businessLogicService.doBusinessLogic();
    } catch (Exception e) {
        log.error(e);
    }
}
crabe
  • 322
  • 4
  • 15
  • 5
    It's much clearer, safer and convenient to implement the handler for generic errors. Then you don't need to remember about every scheduled task to wrap it with try-catch. Apart from that, if you will have 1000 different tasks one day and later you will need to change exception handling for all of them, then good luck if you have to modify all of them. – Mariusz.v7 Aug 13 '17 at 11:10
  • 2
    Agreed, I thought the error handler wasn't until Spring V4 but I see now I was wrong it wasn't *required* until V4, my bad. – crabe Aug 18 '17 at 07:41