7

I have made task using Spring @Scheduled annotation, but for some reason it is executing task twice. My Spring Framework version is 3.0.2.

@Service
public class ReportService {

    @Scheduled(fixedDelay=1000 * 60 * 60* 24)
    @Transactional
    public void dailyReportTask()
    {
        ... code here ...
    }

}

Here is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    <task:scheduler id="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="1" />
    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
</beans>
newbie
  • 24,286
  • 80
  • 201
  • 301
  • Can you paste some of the relevant application context or other such configuration? Is there perhaps another scheduled task that's calling this one? – jasonmp85 May 31 '10 at 10:37

10 Answers10

7

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.

mike_m
  • 1,526
  • 4
  • 14
  • 19
Chinbold Gansukh
  • 1,809
  • 1
  • 15
  • 6
2

I had this same problem, and I eventually found out that the problem was occurring as a result of the beans being created in the root context as well as the servlet context.

So, to fix this, you need to separate the creation of the beans into the appropriate contexts.

This answer explains really well how to that and was what fixed my problem.

Community
  • 1
  • 1
jlars62
  • 7,183
  • 7
  • 39
  • 60
1

I just had this problem recently and it was caused by my app being deployed twice in Tomcat by eclipse. The problem was that I had renamed my application in eclipse but the "wb-module deploy-name" specified in the "org.eclipse.wst.common.component" .settings file still had the old name.

In the tomcat manager, I could see that I had 2 apps running with different names.

wesker317
  • 2,172
  • 1
  • 16
  • 11
1

According to this post: http://www.vodori.com/blog/spring3scheduler.html

Spring 3.0.0 Release had a bug where web apps with a task scheduler would end up executing scheduled methods twice. This has been resolved in Spring 3.0.1.

There has been another bug reported which affects Version/s: 3.0.2 https://jira.springsource.org/browse/SPR-7216

Which should be fixed in Version/s: 3.0.3.

Cojones
  • 1,906
  • 22
  • 25
0

Where are you actually running it? Your PC? Single server? 2 x load-balanced app servers?

Could be it's running on (a) your PC and (b) your server, so it just looks like it's running twice, if you see what I mean: it's correctly running once, just on two distinct locations.

Brian
  • 6,391
  • 3
  • 33
  • 49
  • Just running on my development machine ... it has only one istance running ... I run it from eclipse ... – newbie May 31 '10 at 10:52
  • Is it running on an app server on your machine, e.g. Tomcat, JBoss, Glassfish, to which you deploy from Eclipse? Or is it running as a standalone app? Eclipse may be letting you run a 2nd app while a first one is still actually running. – Brian May 31 '10 at 14:04
  • Its Eclipse embedded tomcat 6 server. And Im usre I have just one instance running, i checked it from task manager. – newbie Jun 01 '10 at 13:42
  • Interesting. If it was me, I would set up a standalone Tomcat 6 on my PC and deploy from Eclipse to that instead. If the problem still manifests, at least you can be sure that's a code/application problem. I'd also maybe change the scheduling to run once per hour to see if it continues to run the new schedule twice even on that separate deployed instance – Brian Jun 02 '10 at 08:05
0

Check if you have any manual scheduler config in your configuration files (through Java/XML). I'ved the same problem, and I discover that my config was loading my scheduler class twice:

In Java:

package com.mywork.br.myschuedulerpackage;
{...}
@Configuration
@EnableScheduling
public class SchedulerConfiguration {

    @Bean
    public CTXDataImporterScheduler ctxDataImporterScheduler() {
        return new CTXDataImporterScheduler();
    }
}

In XML applicationContext.xml:

<context:component-scan base-package="com.mywork.br.myschuedulerpackage" />

And in my scheduler class, I had @Component annotation thats was catch by the component scan and loaded a second time causing the @scheduler methods being executed twice. I removed the Java config and then is working well now!

Mr. Anderson
  • 1,465
  • 1
  • 14
  • 15
0

To solve twice-working of @Scheduled method just delete ContextLoaderListener from you web.xml (if you use web.xml-based application):

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Or if you use WebApplicationInitializer-based application just delete a string that adds ContextLoaderListener:

package com.dropbox.shortener.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // (!) Delete the next string
        // container.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(WebConfig.class);

        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        setupCharEncodingFilter(container);
    }

    private void setupCharEncodingFilter(ServletContext container) {
        container.setInitParameter("defaultHtmlEscape", "true");

        FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
        charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
        charEncodingFilterReg.setInitParameter("forceEncoding", "true");
        charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*");
     }
}
Lord Nighton
  • 1,670
  • 21
  • 15
0

Use @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) on your bean

0
Disabling below will work.
 <!-- <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> -->
blackpanther
  • 10,998
  • 11
  • 48
  • 78
Ankur Srivastava
  • 855
  • 9
  • 10
-1

One solution I would suggest is to do component scat like this

-In application context

<context:component-scan base-package="com.abc.cde.dao" />

In yourservlet-servlet.xml

<!-- package that had all the @Controller classes -->

I this way the servlet is only loaded if the web.xml is loaded Similar can be done for task

Hans Then
  • 10,935
  • 3
  • 32
  • 51
J-P
  • 1