Spring BeanDefinitionStoreException

1. Panoramica

In questo articolo, discuteremo della Spring org.springframework.beans.factory.BeanDefinitionStoreException : questa è in genere la responsabilità di una BeanFactory quando una definizione di bean non è valida, il caricamento di quel bean è problematico. L'articolo discuterà le cause più comuni di questa eccezione insieme alla soluzione per ciascuna di esse.

2. Causa: java.io.FileNotFoundException

Esistono più possibili cause per cui l' eccezione BeanDefinitionStoreException può essere causata da una IOException sottostante :

2.1. IOException durante l' analisi del documento XML dalla risorsa ServletContext

Questo di solito accade in un'applicazione Web Spring, quando un DispatcherServlet è impostato nel web.xml per Spring MVC:

 mvc org.springframework.web.servlet.DispatcherServlet 

Per impostazione predefinita, Spring cercherà un file chiamato esattamente springMvcServlet-servlet.xml nella directory / WEB-INF dell'applicazione web.

Se questo file non esiste, verrà generata la seguente eccezione:

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 soluzione è ovviamente assicurarsi che il file mvc-servlet.xml esista effettivamente in / WEB-INF ; in caso contrario, è possibile crearne uno di esempio:

2.2. IOException durante l' analisi del documento XML dalla risorsa del percorso di classe

Questo di solito accade quando qualcosa nell'applicazione punta a una risorsa XML che non esiste o non è posizionata dove dovrebbe essere.

Indicare una tale risorsa può avvenire in molti modi.

Usando ad esempio la configurazione Java, questo potrebbe essere simile a:

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

In XML, questo sarà:

O anche creando manualmente un contesto XML Spring:

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

Tutti questi porteranno alla stessa eccezione se il file non esiste:

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 soluzione è creare il file e metterlo nella directory / src / main / resources del progetto - in questo modo, il file esisterà nel classpath e sarà trovato e utilizzato da Spring.

3. Causa: impossibile risolvere il segnaposto ...

Questo errore si verifica quando Spring tenta di risolvere una proprietà ma non è in grado di farlo, per uno dei tanti possibili motivi.

Ma prima, l'uso della proprietà - questo può essere usato in XML:

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

La proprietà potrebbe essere utilizzata anche nel codice Java:

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

La prima cosa da verificare è che il nome della proprietà corrisponda effettivamente alla definizione della proprietà; in questo esempio, dobbiamo avere la seguente proprietà definita:

some.property=someValue

Quindi, dobbiamo controllare dove è definito il file delle proprietà in Spring - questo è descritto in dettaglio nel mio Tutorial Proprietà con Spring. Una buona pratica da seguire è avere tutti i file delle proprietà nella directory / src / main / resources dell'applicazione e caricarli tramite:

"classpath:app.properties"

Andando avanti dall'ovvio, un'altra possibile causa per cui Spring non è in grado di risolvere la proprietà è che potrebbero esserci più bean PropertyPlaceholderConfigurer nel contesto Spring (o più elementi segnaposto di proprietà )

In tal caso, la soluzione consiste nel comprimerli in uno singolo o nel configurare quello nel contesto padre con ignoreUnresolhablePlaceholders .

4. Causa: java.lang.NoSuchMethodError

Questo errore si presenta in una varietà di forme, una delle più comuni è:

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;

Questo di solito accade quando ci sono più versioni di Spring sul classpath. Avere una versione precedente di Spring accidentalmente sul classpath del progetto è più comune di quanto si potrebbe pensare: ho descritto il problema e la soluzione per questo nell'articolo Spring Security with Maven.

In breve, la soluzione per questo errore è semplice: controlla tutti i vasi Spring sul classpath e assicurati che abbiano tutti la stessa versione e quella versione è 3.0 o successiva.

Allo stesso modo, l'eccezione non è limitata al bean MutablePropertyValues : ci sono molte altre incarnazioni dello stesso problema, causate dalla stessa incoerenza di versione:

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. Causa: java.lang.NoClassDefFoundError

Un problema comune, correlato in modo simile a Maven e alle dipendenze Spring esistenti è:

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

Ciò si verifica quando la funzionalità transazionale è configurata nella configurazione XML:

Le NoClassDefFoundError significa che il supporto Spring transazionale - cioè molla tx - non esiste nel classpath.

La soluzione è semplice: spring-tx deve essere definito nel Maven pom:

 org.springframework spring-tx 4.1.0.RELEASE 

Ovviamente questo non si limita alla funzionalità di transazione: viene generato un errore simile se manca anche AOP:

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

I barattoli che ora sono richiesti sono: spring-aop (e implicitamente aopalliance ):

 org.springframework spring-aop 4.1.0.RELEASE 

6. Conclusione

Alla fine di questo articolo, dovremmo avere una mappa chiara per esplorare la varietà di cause e problemi che possono portare a un'eccezione del negozio di definizioni di fagioli , nonché una buona conoscenza di come risolvere tutti questi problemi.

L'implementazione di alcuni di questi esempi di eccezioni può essere trovata nel progetto github: questo è un progetto basato su Eclipse, quindi dovrebbe essere facile da importare ed eseguire così com'è.