Exception handling for Spring 3.2 "@Scheduled" annotation
Asked Answered
L

3

20

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
Largess answered 4/6, 2014 at 7:36 Comment(5)
What do you mean by customized exception handling? Can't you just handle any exception inside the @Scheduled method?Birchfield
@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 ?Largess
Depending on your needs, Spring AOP might be worth looking intoBirchfield
@geoand, if you any example can you explain me here ? thank you.Largess
If you need to do some stuff before all @Scheduled method, you should check out Spring AOP.docs.spring.io/spring-framework/docs/current/…Birchfield
C
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"/>
Crural answered 1/3, 2016 at 18:41 Comment(2)
One note: if you have <task:scheduler>, the lines above replace it. You replace your Task Scheduler with this Task:Annotation Driven + 2 beans. Afterwards, change your <task:scheduled-tasks scheduler="yourThreadPoolTaskScheduler"> to point to this new scheduler name.Encumbrance
See: https://mcmap.net/q/511069/-universal-exception-handler-for-scheduled-tasks-in-spring-boot-with-java-configurationEncumbrance
C
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
Crawford answered 13/8, 2017 at 10:56 Comment(0)
C
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"/>
Crural answered 1/3, 2016 at 18:41 Comment(2)
One note: if you have <task:scheduler>, the lines above replace it. You replace your Task Scheduler with this Task:Annotation Driven + 2 beans. Afterwards, change your <task:scheduled-tasks scheduler="yourThreadPoolTaskScheduler"> to point to this new scheduler name.Encumbrance
See: https://mcmap.net/q/511069/-universal-exception-handler-for-scheduled-tasks-in-spring-boot-with-java-configurationEncumbrance
M
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);
    }
}
Machicolation answered 27/7, 2015 at 13:13 Comment(2)
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.Crawford
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.Machicolation

© 2022 - 2024 — McMap. All rights reserved.