问题
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 )
回答1:
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).
回答2:
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/>
回答3:
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.
回答4:
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.
回答5:
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.
回答6:
I had the <task:annotation-driven/>
defined twice in the context xml. Removing that worked for me.
来源:https://stackoverflow.com/questions/5440429/springs-scheduled-error-only-one-asyncannotationbeanpostprocessor-may-exist