Spring BeanDefinitionStoreException – SpringBeanDefinitionStoreException

最后修改: 2013年 5月 11日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we will discuss the Spring org.springframework.beans.factory.BeanDefinitionStoreException – this is typically the responsibility of a BeanFactory when a bean definition is invalid, the loading of that bean is problematic. The article will discuss the most common causes of this exception along with the solution for each one.

在这篇文章中,我们将讨论Spring org.springframework.beans.factory.BeanDefinitionStoreException–这通常是BeanFactory的责任,当一个bean定义无效时,该bean的加载就有问题。这篇文章将讨论造成这种异常的最常见的原因,以及每个原因的解决方案。

2. Cause: java.io.FileNotFoundException

2.原因 java.io.FileNotFoundException

There are multiple possible causes that the BeanDefinitionStoreException may be caused by an underlying IOException:

有多种可能的原因,BeanDefinitionStoreException可能是由底层的IOException引起的。

2.1. IOException Parsing XML Document From ServletContext Resource

2.1.IOException从ServletContext资源解析XML文档

This usually happens in a Spring Web application, when a DispatcherServlet is set up in the web.xml for Spring MVC:

这通常发生在Spring Web应用程序中,当Spring MVC的web.xml中设置了一个DispatcherServlet

<servlet>  
   <servlet-name>mvc</servlet-name>  
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
</servlet>

By default, Spring will look for a file called exactly springMvcServlet-servlet.xml in the /WEB-INF directory of the web application.

默认情况下,Spring会在Web应用的/WEB-INF目录下寻找一个确切称为springMvcServlet-servlet.xml的文件。

If this file doesn’t exist, then the following exception will be thrown:

如果这个文件不存在,那么就会抛出以下异常。

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]

The solution is of course to make sure the mvc-servlet.xml file indeed exists under /WEB-INF; if it doesn’t, then a sample one can be created:

解决方案当然是确保mvc-servlet.xml文件确实存在于/WEB-INF下;如果它不存在,那么可以创建一个样本。

<?xml version="1.0" encoding="UTF-8"?>
<beans 
   xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" >

</beans>

2.2. IOException Parsing XML Document From Class Path Resource

2.2.IOException Parsing XML Document From Class Path Resource

This usually happens when something in the application points to an XML resource that doesn’t exist, or is not placed where it should be.

这通常发生在应用程序中的某些东西指向一个不存在的XML资源,或者没有放在它应该在的位置。

Pointing to such a resource may happen in a variety of ways.

指向这样的资源可能以各种方式发生。

Using for example Java Configuration, this may look like:

例如,使用Java配置,这可能看起来像。

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

In XML, this will be:

在XML中,这将是。

<import resource="beans.xml"/>

Or even by creating an Spring XML context manually:

甚至可以通过手动创建一个Spring XML上下文。

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

All of these will leads to the same exception if the file doesn’t exist:

如果文件不存在,所有这些都会导致同样的异常。

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]

The solution is create the file and to place it under the /src/main/resources directory of the project – this way, the file will exist on the classpath and it will be found and used by Spring.

解决方案是创建该文件,并将其放在项目的/src/main/resources目录下–这样,该文件将存在于classpath上,并被Spring找到和使用。

3. Cause: Could Not Resolve Placeholder …

3.原因 无法解决占位符…

This error occurs when Spring tries to resolve a property but is not able to – for one of many possible reasons.

当Spring试图解决一个属性但无法解决时,就会出现这个错误–由于许多可能的原因之一。

But first, the usage of the property – this may be used in XML:

但首先,属性的用法–这可能是在XML中使用。

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

The property could also be used in Java code:

该属性也可以在Java代码中使用。

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

First thing to check is that the name of the property actually matches the property definition; in this example, we need to have the following property defined:

首先要检查的是属性的名称是否真的与属性定义相符;在这个例子中,我们需要有以下的属性定义。

some.property=someValue

Then, we need to check where the properties file is defined in Spring – this is described in detail in my Properties with Spring Tutorial. A good best practice to follow is to have all properties files under the /src/main/resources directory of the application and to load them up via:

然后,我们需要检查属性文件在Spring中的定义位置–这在我的使用Spring的属性教程中有详细描述。一个好的最佳做法是将所有属性文件放在应用程序的/src/main/resources目录下,并通过以下方式加载它们。

"classpath:app.properties"

Moving on from the obvious – another possible cause that Spring is not able to resolve the property is that there may be multiple PropertyPlaceholderConfigurer beans in the Spring context (or multiple property-placeholder elements)

从显而易见的角度来看,Spring无法解决该属性的另一个可能原因是,Spring上下文中可能存在多个PropertyPlaceholderConfigurer Bean(或多个property-placeholder元素)。

If that is the case, then the solution is either collapsing these into a single one, or configuring the one in the parent context with ignoreUnresolvablePlaceholders.

如果是这种情况,那么解决方案是将这些折叠成一个单一的,或者在父级上下文中配置ignoreUnresolvablePlaceholders的那个。

4. Cause: java.lang.NoSuchMethodError

4.原因 java.lang.NoSuchMethodError

This error comes in a variety of forms – one of the more common ones is:

这种错误有多种形式–其中一个比较常见的形式是。

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;

This usually happens when there are multiple versions of Spring on the classpath. Having an older version of Spring accidentally on the project classpath is more common than one would think – I described the problem and the solution for this in the Spring Security with Maven article.

这通常发生在classpath上有多个版本的Spring。在项目的classpath上意外出现一个较早版本的Spring比人们想象的更常见–我在Spring Security with Maven文章中描述了这个问题和解决方案

In short, the solution for this error is simple – check all the Spring jars on the classpath and make sure that they all have the same version – and that version is 3.0 or above.

简而言之,解决这个错误的方法很简单–检查classpath上的所有Spring jars,确保它们都有相同的版本–而且这个版本是3.0或以上。

Similarly, the exception is not restricted to the MutablePropertyValues bean – there are several other incarnations of the same problem, caused by the same version inconsistency:

同样,这个异常并不局限于MutablePropertyValuesBean–同样的问题还有其他几种化身,由同样的版本不一致引起。

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

5.原因 java.lang.NoClassDefFoundError

A common problem, similarly related to Maven and the existing Spring dependencies is:

与Maven和现有Spring依赖关系类似的一个常见问题是。

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

This occurs when transactional functionality is configured in the XML configuration:

当在XML配置中配置了事务性功能时,就会出现这种情况。

<tx:annotation-driven/>

The NoClassDefFoundError means that the Spring Transactional support – namely spring-tx – does not exist on the classpath.

NoClassDefFoundError意味着Spring事务性支持–即spring-tx–在classpath上不存在。

The solution is simple – spring-tx needs to be defined in the Maven pom:

解决方案很简单–spring-tx需要在Maven pom中定义。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.1.0.RELEASE</version>
</dependency>

Of course this is not limited to the transaction functionality – a similar error is thrown if AOP is missing as well:

当然,这并不局限于交易功能–如果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

The jars that are now required are: spring-aop (and implicitly aopalliance):

现在需要的罐子是。spring-aop(以及隐含的aopalliance)。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.0.RELEASE</version>
</dependency>

6. Conclusion

6.结论

At the end of this article, we should have a clear map to navigate the variety of causes and problems that may lead to a Bean Definition Store Exception as well as a good grasp on how to fix all of these problems.

在本文结束时,我们应该有一张清晰的地图来浏览可能导致Bean定义存储异常的各种原因和问题,以及对如何修复所有这些问题的良好把握。

The implementation of some of these exceptions examples can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

可以在github项目中找到其中一些异常的实现–这是一个基于Eclipse的项目,所以应该很容易导入并按原样运行。