web-dev-qa-db-fra.com

Erreur @Scheduled du printemps: un seul AsyncAnnotationBeanPostProcessor peut exister dans le contexte

J'essaie l'annotation @Scheduled du printemps 3. Voici ma 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>

Et voici ma classe de service:

@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());
  }
}

Cela fonctionne bien lors du test dans mon eclispe + junit, lors du test d'une méthode timeConsumingJob, je peux voir que secondly () continue à émettre un message en second lieu.

Mais lorsqu'il est déployé dans un conteneur (Resin/4.0.13), il génère:

[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)

J'ai cherché mais je trouve rarement des situations similaires, je pense que c'est le paramètre le plus fondamental, mais je ne sais pas pourquoi cela ne fonctionne pas.

Quelqu'un peut-il jeter un coup d'oeil? Merci beaucoup !

(Spring 3.0.5, Resin 4.0.13)

------------ mis à jour ---------

Après avoir creusé plus profondément, j'ai découvert que le fichier app.xml est importé par un autre fichier XML. C’est peut-être pour cette raison que task:annotation-driven ne fonctionne pas. 

Eh bien, après avoir réorganisé l'emplacement de certains haricots, le problème est résolu, mais je me sens toujours perplexe. (Parce que cela a bien fonctionné et que other.xml a besoin de beans dans app.xml)

25
smallufo

Le contexte d'application est en cours d'initialisation deux fois, mais org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser échoue lors de l'enregistrement du bean ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME.

J'ai rencontré ce problème dans des tests unitaires où @ContextConfiguration ("/ path/to/applicationContext.xml") était accidentellement sur la classe de test parent et la classe de test enfant (avec la valeur par défaut de inheritLocations true).

15

J'ai fait face à cela une fois après avoir implémenté notre propre AsyncTaskExecutor et oublié de supprimer le <task: annotation-driven/> par défaut

Vérifiez si vous avez quelque chose comme ça, si oui, supprimez l'une des tâches.

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

<task:annotation-driven/>
8
Rajesh

Cela se produit lorsque spring analyse deux fois le texte <task:annotation-driven/> dans un fichier XML de configuration.

Pour moi, cela se passait parce que applicationContext-root.xml et applicationContext-where-annotation-driven-is-specififed.xml ont été importés dans ma section WEB.xml dans <context-param>.

Ne laisser que applicationContext-root.xml dans WEB.xml a résolu le problème.

7
Babken Vardanyan

J'ai eu ce problème quand j'ai copié applicationContext.xml et en ai créé un nouveau appelé applicationContextAdditional.xml. Je n'ai pas essayé de trouver la raison, mais les deux contenaient un espace de noms

<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>

quand j'ai enlevé le namespace du second, mon problème a été résolu. Peut-être que ça aide quelqu'un.

6
Betlista

Dans mon cas, cela était dû au changement de version. Il existe donc plusieurs versions de fichiers JAR dans l'emplacement du fichier de sortie (chaque fichier JAR contient donc un 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]

pendant que j'utilise 1.0 dans ce cas. Je dois donc supprimer manuellement C:/.../lib/xxx-2.0.jar à cet emplacement, et je peux voir que xxx-1.0.jar se trouve également dans ce répertoire. Après la suppression manuelle, cela fonctionne normalement.

0
MewX