Spring BeanDefinitionStoreException

1. Übersicht

In diesem Artikel werden wir die Spring org.springframework.beans.factory.BeanDefinitionStoreException diskutieren. Dies liegt normalerweise in der Verantwortung einer BeanFactory, wenn eine Bean-Definition ungültig ist und das Laden dieser Bean problematisch ist. In diesem Artikel werden die häufigsten Ursachen dieser Ausnahme sowie die jeweilige Lösung erläutert.

2. Ursache: java.io.FileNotFoundException

Es gibt mehrere mögliche Ursachen dafür, dass die BeanDefinitionStoreException durch eine zugrunde liegende IOException verursacht wird :

2.1. IOException Parsing von XML-Dokument aus ServletContext-Ressource

Dies geschieht normalerweise in einer Spring-Webanwendung, wenn ein DispatcherServlet in der web.xml für Spring MVC eingerichtet ist:

 mvc org.springframework.web.servlet.DispatcherServlet 

Standardmäßig wird Frühling für eine Datei genau genannt aussieht springMvcServlet-servlet.xml im / WEB-INF - Verzeichnis der Web - Anwendung.

Wenn diese Datei nicht vorhanden ist, wird die folgende Ausnahme ausgelöst:

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]

Die Lösung besteht natürlich darin, sicherzustellen, dass die Datei mvc-servlet.xml tatsächlich unter / WEB-INF vorhanden ist . Wenn dies nicht der Fall ist, kann ein Beispiel erstellt werden:

2.2. IOException Parsen von XML-Dokumenten aus Klassenpfadressourcen

Dies geschieht normalerweise, wenn etwas in der Anwendung auf eine XML-Ressource verweist, die nicht vorhanden ist oder nicht dort platziert ist, wo sie sein sollte.

Das Zeigen auf eine solche Ressource kann auf verschiedene Arten erfolgen.

Wenn Sie beispielsweise die Java-Konfiguration verwenden, sieht dies möglicherweise folgendermaßen aus:

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

In XML ist dies:

Oder sogar durch manuelles Erstellen eines Spring XML-Kontexts:

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

All dies führt zu derselben Ausnahme, wenn die Datei nicht vorhanden ist:

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]

Die Lösung besteht darin, die Datei zu erstellen und im Verzeichnis / src / main / resources des Projekts abzulegen. Auf diese Weise ist die Datei im Klassenpfad vorhanden und wird von Spring gefunden und verwendet.

3. Ursache: Platzhalter konnte nicht aufgelöst werden…

Dieser Fehler tritt auf, wenn Spring versucht, eine Eigenschaft aufzulösen, dies jedoch aus einem von vielen möglichen Gründen nicht kann.

Aber zuerst die Verwendung der Eigenschaft - dies kann in XML verwendet werden:

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

Die Eigenschaft kann auch in Java-Code verwendet werden:

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

Als erstes muss überprüft werden, ob der Name der Eigenschaft tatsächlich mit der Eigenschaftsdefinition übereinstimmt. In diesem Beispiel muss die folgende Eigenschaft definiert sein:

some.property=someValue

Dann müssen wir überprüfen, wo die Eigenschaftendatei in Spring definiert ist - dies wird ausführlich in meinem Tutorial Eigenschaften mit Spring beschrieben. Es empfiehlt sich, alle Eigenschaftendateien im Verzeichnis / src / main / resources der Anwendung zu speichern und über Folgendes zu laden:

"classpath:app.properties"

Weiter vom Offensichtlichen - Eine weitere mögliche Ursache dafür, dass Spring die Eigenschaft nicht auflösen kann, ist, dass der Spring-Kontext möglicherweise mehrere PropertyPlaceholderConfigurer- Beans enthält (oder mehrere Eigenschaftsplatzhalterelemente ).

Wenn dies der Fall ist, reduziert die Lösung diese entweder zu einer einzigen oder konfiguriert die im übergeordneten Kontext mit ignoreUnresolvablePlaceholders .

4. Ursache: java.lang.NoSuchMethodError

Dieser Fehler tritt in verschiedenen Formen auf - eine der häufigsten ist:

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;

Dies geschieht normalerweise, wenn der Klassenpfad mehrere Versionen von Spring enthält. Eine ältere Version von Spring versehentlich im Projektklassenpfad zu haben, ist häufiger als man denkt - ich habe das Problem und die Lösung dafür im Artikel Spring Security with Maven beschrieben.

Kurz gesagt, die Lösung für diesen Fehler ist einfach: Überprüfen Sie alle Spring-Jars im Klassenpfad und stellen Sie sicher, dass alle dieselbe Version haben. Diese Version ist 3.0 oder höher.

In ähnlicher Weise ist die Ausnahme nicht auf die MutablePropertyValues- Bean beschränkt. Es gibt mehrere andere Inkarnationen desselben Problems, die durch dieselbe Versionsinkonsistenz verursacht werden:

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

Ein häufiges Problem, das in ähnlicher Weise mit Maven und den vorhandenen Spring-Abhängigkeiten zusammenhängt, ist:

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

Dies tritt auf, wenn die Transaktionsfunktionalität in der XML-Konfiguration konfiguriert ist:

Der NoClassDefFoundError bedeutet, dass die Spring Transactional-Unterstützung - nämlich spring-tx - im Klassenpfad nicht vorhanden ist.

Die Lösung ist einfach: spring-tx muss im Maven pom definiert werden:

 org.springframework spring-tx 4.1.0.RELEASE 

Dies ist natürlich nicht auf die Transaktionsfunktionalität beschränkt - ein ähnlicher Fehler wird ausgelöst, wenn auch AOP fehlt:

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

Die Gläser, die jetzt benötigt werden, sind: spring-aop (und implizit aopalliance ):

 org.springframework spring-aop 4.1.0.RELEASE 

6. Fazit

Am Ende dieses Artikels sollten wir eine übersichtliche Übersicht über die verschiedenen Ursachen und Probleme haben, die zu einer Bean Definition Store-Ausnahme führen können , sowie einen guten Überblick darüber, wie all diese Probleme behoben werden können.

Die Implementierung einiger dieser Ausnahmebeispiele finden Sie im Github-Projekt. Dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.