Spring BeanDefinitionStoreException

1. Vue d'ensemble

Dans cet article, nous discuterons de l' exception Spring org.springframework.beans.factory.BeanDefinitionStoreException - c'est généralement la responsabilité d'un BeanFactory lorsqu'une définition de bean est invalide, le chargement de ce bean est problématique. L'article abordera les causes les plus courantes de cette exception ainsi que la solution pour chacune d'elles.

2. Cause: java.io.FileNotFoundException

Il existe plusieurs causes possibles pour lesquelles l' exception BeanDefinitionStoreException peut être causée par une IOException sous-jacente :

2.1. IOException analyse un document XML à partir de la ressource ServletContext

Cela se produit généralement dans une application Web Spring, lorsqu'un DispatcherServlet est configuré dans le fichier web.xml pour Spring MVC:

 mvc org.springframework.web.servlet.DispatcherServlet 

Par défaut, Spring recherchera un fichier appelé exactement springMvcServlet-servlet.xml dans le répertoire / WEB-INF de l'application Web.

Si ce fichier n'existe pas, l'exception suivante sera levée:

org.springframework.beans.factory.BeanDefinitionStoreException: Ioexception Parsing Xml Document from Servletcontext Resource [/WEB-INF/mvc-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/mvc-servlet.xml]

La solution est bien entendu de s'assurer que le fichier mvc-servlet.xml existe bien sous / WEB-INF ; si ce n'est pas le cas, un exemple peut être créé:

2.2. IOException analyse un document XML à partir d'une ressource de chemin de classe

Cela se produit généralement lorsque quelque chose dans l'application pointe vers une ressource XML qui n'existe pas ou n'est pas placée là où elle devrait être.

Le fait de pointer vers une telle ressource peut se produire de différentes manières.

En utilisant par exemple la configuration Java, cela peut ressembler à:

@Configuration @ImportResource("beans.xml") public class SpringConfig {...}

En XML, ce sera:

Ou même en créant manuellement un contexte Spring XML:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

Tout cela conduira à la même exception si le fichier n'existe pas:

org.springframework.beans.factory.BeanDefinitionStoreException: Ioexception Parsing Xml Document from Servletcontext Resource [/beans.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/beans.xml]

La solution est de créer le fichier et de le placer dans le répertoire / src / main / resources du projet - de cette façon, le fichier existera sur le chemin de classe et il sera trouvé et utilisé par Spring.

3. Cause: impossible de résoudre l'espace réservé…

Cette erreur se produit lorsque Spring essaie de résoudre une propriété mais n'y parvient pas - pour l'une des nombreuses raisons possibles.

Mais d'abord, l'utilisation de la propriété - cela peut être utilisé en XML:

... value="${some.property}" ...

La propriété peut également être utilisée dans le code Java:

@Value("${some.property}") private String someProperty;

La première chose à vérifier est que le nom de la propriété correspond réellement à la définition de la propriété; dans cet exemple, nous devons définir la propriété suivante:

some.property=someValue

Ensuite, nous devons vérifier où le fichier de propriétés est défini dans Spring - cela est décrit en détail dans mon Tutoriel Propriétés avec Spring. Une bonne pratique à suivre est d'avoir tous les fichiers de propriétés dans le répertoire / src / main / resources de l'application et de les charger via:

"classpath:app.properties"

Passant de l'évidence - une autre cause possible pour laquelle Spring n'est pas en mesure de résoudre la propriété est qu'il peut y avoir plusieurs beans PropertyPlaceholderConfigurer dans le contexte Spring (ou plusieurs éléments d' espace réservé de propriété )

Si tel est le cas, la solution consiste soit à les réduire en un seul, soit à configurer celui dans le contexte parent avec ignoreUnresolvablePlaceholders .

4. Cause: java.lang.NoSuchMethodError

Cette erreur se présente sous diverses formes - l'une des plus courantes est:

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml]; nested exception is java.lang.NoSuchMethodError: org.springframework.beans.MutablePropertyValues.add (Ljava/lang/String;Ljava/lang/Object;) Lorg/springframework/beans/MutablePropertyValues;

Cela se produit généralement lorsqu'il existe plusieurs versions de Spring sur le chemin de classe. Avoir une ancienne version de Spring accidentellement sur le chemin de classe du projet est plus courant qu'on ne le pense - j'ai décrit le problème et la solution à cela dans l'article Spring Security with Maven.

En bref, la solution à cette erreur est simple - vérifiez tous les jars Spring sur le chemin de classe et assurez-vous qu'ils ont tous la même version - et que cette version est 3.0 ou supérieure.

De même, l'exception n'est pas limitée au bean MutablePropertyValues - il existe plusieurs autres incarnations du même problème, causées par la même incohérence de version:

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml]; - nested exception is java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.makeAccessible(Ljava/lang/reflect/Constructor;)V

5. Cause: java.lang.NoClassDefFoundError

Un problème courant, similaire à Maven et aux dépendances Spring existantes, est:

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/transaction/interceptor/TransactionInterceptor

Cela se produit lorsque la fonctionnalité transactionnelle est configurée dans la configuration XML:

Les NoClassDefFoundError signifie que le support transactionnelles ressort - à savoir printemps-tx - n'existe pas sur le chemin de classe.

La solution est simple - spring-tx doit être défini dans le pom Maven:

 org.springframework spring-tx 4.1.0.RELEASE 

Bien sûr, cela ne se limite pas à la fonctionnalité de transaction - une erreur similaire est générée si AOP est également manquant:

Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml]; nested exception is java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice

Les pots qui sont maintenant requis sont: spring-aop (et implicitement aopalliance ):

 org.springframework spring-aop 4.1.0.RELEASE 

6. Conclusion

À la fin de cet article, nous devrions avoir une carte claire pour parcourir la variété des causes et des problèmes pouvant conduire à une exception de magasin de définitions de bean ainsi qu'une bonne compréhension de la façon de résoudre tous ces problèmes.

L'implémentation de certains de ces exemples d'exceptions peut être trouvée dans le projet github - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.