26
votes

I am trying Spring 3's @Scheduled annotation . Here is my configuration (app.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:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:task="http://www.springframework.org/schema/task"
  xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
      http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
      "
>

  <context:component-scan base-package="destiny.web"/>  
  <context:annotation-config/>
  // other beans

  <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
  <task:executor  id="myExecutor"  pool-size="5"/>
  <task:scheduler id="myScheduler" pool-size="10"/>
</beans>

And this is my service class :

@Service
public class ServiceImpl implements Service , Serializable
{
  //other injections

  @Override
  @Transactional
  public void timeConsumingJob()
  {
    try
    {
      Thread.sleep(10*1000);
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }

  @Override
  @Scheduled(cron="* * * * * ?") 
  public void secondly()
  {
    System.err.println("secondly : it is " + new Date());
  }
}

It works fine when testing in my eclispe + junit , when testing a timeConsumingJob method , I can see secondly() continues outputting message secondly.

But when deployed to a container (Resin/4.0.13) , it throws :

[11-03-26 12:10:14.834] {main} org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Only one AsyncAnnotationBeanPostProcessor may exist within the context.
Offending resource: class path resource [app.xml]
 at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
 at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
 at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:72)
 at org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser.parse(AnnotationDrivenBeanDefinitionParser.java:82)

I searched but seldom find similar situations , I think it is the most basic setting , but don't know why it doesn't work .

Can somebody take a look at it ? Thanks a lot !

(Spring 3.0.5 , Resin 4.0.13)

------------ updated ---------

After I dig deeper , I found the app.xml is imported by another xml. Maybe this is the reason makes task:annotation-driven not working.

Well , after re-arranging some beans' location , it is solved, but I still feel puzzled. (Because it worked fine , and other.xml needs beans in app.xml )

7
Arr you sure you're not including app.xml twice, somehow? How have you configured that?skaffman
Hi , I am sure app.xml is included once. (in web.xml's context-param's contextConfigLocation )smallufo
Hi, thnx, I had same problem and got solved now. In my case also, the xml file was imported at two places and so was getting this error but then removed that import from one place and now resolved this error.Mital Pritmani

7 Answers

15
votes

The application context is being initialized twice but org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser fails registering bean ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME second time.

I encountered this problem in unit tests where @ContextConfiguration("/path/to/applicationContext.xml") was accidentally on both the parent test class and child test class (with default value of inheritLocations true).

8
votes

I have faced this once after implementing our own AsyncTaskExecutor and forgetting to remove default <task:annotation-driven/>

Check if you have something like this, if yes remove one of the task.

<task:annotation-driven executor="customAsyncTaskExecutor" scheduler="taskScheduler"/>

<task:annotation-driven/>
7
votes

This happens when spring parses the <task:annotation-driven/> text twice in a config XML.

For me this was happening because both applicationContext-root.xml and applicationContext-where-annotation-driven-is-specififed.xml were imported in my WEB.xml in <context-param> section.

Leaving only applicationContext-root.xml in WEB.xml solved the issue.

6
votes

I had this problem when I copied applicationContext.xml and created new one called applicationContextAdditional.xml. I didn't try to find the reason, but both contained namespace

<bean ...
    xmlns:task="http://www.springframework.org/schema/task"
    ...
    xsi:schemaLocation="
   http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" >

    ...

</bean>

when I removed the namespace from the second one my problem was solved. Maybe it helps someone.

1
votes

In my case, this was caused by switching versions, thereby in the output file location there are multiple version of jars (and therefore each jar contains a AnnotationBean):

2018-02-19 13:38:44,913 [RMI TCP Connection(3)-127.0.0.1] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Only one ScheduledAnnotationBeanPostProcessor may exist within the context.
Offending resource: URL [jar:file:/C:/.../lib/xxx-2.0.jar!/META-INF/spring/xxx.xml]

while I'm using 1.0 in this case. So I have to manually delete C:/.../lib/xxx-2.0.jar in this location, and I'm able to see xxx-1.0.jar is also in this directory. After the manual deletion, it works normally.

1
votes

I had the <task:annotation-driven/> defined twice in the context xml. Removing that worked for me.

0
votes

That error, about

Only one AsyncAnnotationBeanPostProcessor may exist within the context

, can appear in one more case. I do not insist, that that must help you, maybe you really have some complicated problem, described in other posts, but no one of them helped me.

What did help, was simple

mvn clean

, for the project somehow had created some duplicated files and those caused the problem. And a simple clean had... ehm... cleaned them.

That situation, for example, can happen after a merge with a branch with a higher version of the project.