I have a simple test method here that is set to run every 5 seconds and it does, but looking at the System.out you can see it appears to be doing something odd.
I know the answer!!
Don't init your Scheduled twice
Loot at your web log :
WebApplicationContext
once and servlet once
so in your servlet.xml
don't do like this
import resource="classpath:applicationContext.xml"
If you look at the documentation, there is a note that explicitly calls out this phenomenon.
The note is under section 25.5.1 at this link, and reads:
Make sure that you are not initializing multiple instances of the same @Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use @Configurable on bean classes which are annotated with @Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the @Configurable aspect, with the consequence of each @Scheduled method being invoked twice.
I understand that this is merely suggestion at this point, but I do not think we have enough information to diagnose the issue further.
Had the same issue with my springboot-application, the Scheduler runs twice.
Reason was, as mentioned multiple times in earlier comments, that the bean is initialized multiple times.
My solution was:
In the code- this was the change i´ve made:
// @Component <------ Removed
public class FileTransferScheduler {
private final Logger logger = LoggerFactory.getLogger(FileTransferScheduler.class);
@Autowired
private ExtractorService extractorService;
@Scheduled(cron = "* /1 * * * *")
public void scheduleFileTransfer() {
logger.info("Triggered cronjob to transfer new uploads to dms...");
extractorService.extractTmcUploads();
}
}
...and then this change in the main method of the springboot-application:
@EnableScheduling
@SpringBootApplication
public class InsidersExtractorApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// The Scheduler Class needs to be added manually, because it dont have to be defined as Bean
return application.sources(InsidersExtractorApplication.class, FileTransferScheduler.class);
}
public static void main(String[] args) {
SpringApplication.run(InsidersExtractorApplication.class, args);
}
}
it is happening because of context listener
Just remove
< listener >
< listener-class >org.springframework.web.context.ContextLoaderListener< /listener-class >
< /listener >
from web.xml it should work.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security/spring-security.xml
/WEB-INF/spring/mongo/mongo-config.xml
/WEB-INF/spring/appServlet/spring-context.xml
</param-value>
</context-param>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/spring-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
That is my web.xml . So , you can see that "/WEB-INF/spring/appServlet/spring-context.xml" is loaded twice (once in context-param , once in servlet -> init-param ).
I had the same problem, I tried all the suggested methods and nothing worked for me. Finally I was able to find the solution by removing the extension to 'SpringBootServletInitializer' and the 'configure' method of my WebApplication class and with this I stopped duplicating my Scheduled Task.