@Scheduled annotation methods do not work in Spring Boot application
tl; dr: Can you think of anyway I might be looking for where @Scheduled
tasks are not running in a Spring Boot application?
I implemented the example , but it worked fine, however, in a more complex Spring boot application I am working on, I can't get the methods @Scheduled
to run.
My main class looks like this:
package com.mypackage.myapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@SpringBootApplication
@EnableWebSecurity
@EnableScheduling
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
and the component running the scheduled application looks like this:
(...)
@Component
public class MyComponent {
private static final Logger logger = LoggerFactory.getLogger(MyComponent.class);
(...)
@Scheduled(fixedRate = 5000)
public void myScheduledTask() {
logger.info("Executing scheduled task");
(...)
}
}
The whole application is obviously more complex, but this is essentially it. Unfortunately "Executing scheduled task"
not showing up in the logs, also if I debug the breakpoint is never hit.
As I said, a minimal example works for me, however in my application it doesn't. Can you think of any case that I could test where tasks are not running @Scheduled
? For example, can the configuration be overridden by anything? Can anything interfere?
I am using version 1.5.1.RELEASE
.
source to share
I think I figured it out. I have another component that implements SmartLifecycle
, and the method start()
contains a loop while
that I never receive (intentionally, reading from a Kafka stream). This essentially leads to initialization stuck and hence the method is @Scheduled
never scheduled.
I could just reproduce this in a minimal example with while(true)
. Once I succeed, the method @Scheduled
fails, when I delete while
it works fine.
package com.mypackage.myapp;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;
@Component
public class StartLoop implements SmartLifecycle {
private static final Logger log = LoggerFactory.getLogger(StartLoop.class);
private static final int LAST_PHASE = Integer.MAX_VALUE;
private boolean running;
@Override
public void start() {
runMyCode();
}
private void runMyCode() {
running = true;
log.info("Starting ...");
while (running) {
try {
log.info("running");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public boolean isRunning() {
return running;
}
@Override
public void stop() {
log.info("Stopping ...");
}
@Override
public void stop(Runnable callback) {
callback.run();
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public int getPhase() {
return LAST_PHASE;
}
}
If now we replace the method start()
with
@Override
public void start() {
CompletableFuture.runAsync(this::runMyCode);
}
it works great.
source to share