Home > Software design >  Java Spring @Scheduled Cron Task
Java Spring @Scheduled Cron Task

Time:03-19

I am currently bumping into an issue whilst using the @Scheduled (cron) annotation in Spring.

@Scheduled(cron = "0 0 3 * * MON-FRI", zone = "Europe/Berlin")

This task executes every day at 3 o'clock in the morning (Monday-Friday):

  • 03:00:00,278 - 03:00:08,269
  • 03:00:08,269 - 03:00:15,451

My question is, why does this task execute twice? I have stated that it should only run at minute "0" and "0" seconds, but this seems off (see execution times). I have two such tasks and both have this issue. Is there anybody that may know the reason on why this is happening and how to avoid it?

I am using Spring Boot Version 2.1.6. Note: will be upgrading to Version 2.7 soon.

Edit:

My scheduler class:

@Component
@RequiredArgsConstructor
@Log4j2
public class LdapTask {

    private final IAppUserService appUserService;
    
    private final IEmployeeService employeeService;
    
    //second, minute, hour, day of month, month, day(s) of week
    @Scheduled(cron = "0 0 3 * * MON-FRI", zone = "Europe/Berlin")
    public void blockAppUsers() {
        /* Logic here */
    }
    
    @Scheduled(cron = "0 20 3 * * MON-FRI")
    public void checkEmailAddresses() {
        /* Logic here */
    }
}

Application (Entry for this application):

@SpringBootApplication(exclude = MultipartAutoConfiguration.class)
@EntityScan(basePackages = "...")
@EnableScheduling
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
    
    public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
    }
}

Answer for my problem:

I replaced the overridden method configure from SpringBootServletInitializer body with this:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class, LdapTask.class);
}

instead of:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
}

and removing the @Component Annotation in the LdapTask Class.

As the answer of this post hinted, spring was actually creating two instances of the ApplicationContext, which executed this method twice.

CodePudding user response:

Check carefully logs when initializing application.

Most likely, your scheduler been is initialized twice. One of the reasons may be extending from SpringBootServletInitializer - it may initialize beans once for WebApplicationContext, and once more for Servlet context.

source

P.S. to give you the solution I would need acces to whole src code, as it may even be an extra starter dependency in pom

  • Related