spring异常被吞的一种情形

你是否遇到过下面的情况,控制台无限的输出下面的日志:

Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter. 
Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter. 
Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter. 
Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter. 
Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter.

这个错误只有在和spring集成的情况下才会出现。

每次只要出现这个错误,我都知道是XML出错了,但是具体是那个XML还没法直接确认,因为这里的日志看不出来任何有用的信息。

想定位这个错误,我有一个常见的方法,就是从程序启动的某一个入口断点,然后逐步定位这个错误。

不过这种方式仍然很麻烦,这里要说的是一种迅速定位解决的办法,操作起来很简单。

找到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 类,在下面方法:

protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

这个方法大概在1200行左右。找到这个方法中catch异常的地方:

catch (BeansException ex) {
    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}

throw这一行断点即可,这个地方是最早捕获异常的地方,当Mapper.xml文件出错的时候,这里的异常信息如下: 

异常信息是很详细的,具体异常文字如下:

org.springframework.core.NestedIOException:
Failed to parse mapping resource:
‘file [F:\Liu\Git\bhgl\target\Franchisee-1.0\WEB-INF\classes\com\abel533\property\dao\EmployeeMapper.xml]‘;
nested exception is org.apache.ibatis.builder.BuilderException:
Error creating document instance.
Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。

打开这个出错的XML后,发现一个很无语的错误: 

不知道什么情况,开头多了emplo,基本上只要是 XML 中出什么错,都是类似的异常信息,一般都是 XML 解析出的错。

还有一个问题,为什么出错后只能看到无限输出的一行日志,而看不到这里具体的异常信息呢?

通过追踪代码,发现在org.springframework.beans.factory.support.AbstractBeanFactory类中的方法:

protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
    if (!mbd.isSingleton()) {
        return null;
    }
    try {
        FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
        return getTypeForFactoryBean(factoryBean);
    }
    catch (BeanCreationException ex) {
        // Can only happen when getting a FactoryBean.
        if (logger.isDebugEnabled()) {
            logger.debug("Ignoring bean creation exception on FactoryBean type check: " + ex);
        }
        onSuppressedException(ex);
        return null;
    }
}

这里捕获异常后,直接return null导致异常被吞。

由于这里是最后一层捕获异常的地方,而且这个地方捕获到的异常范围会更广,因此在这里断点查看问题也是很不错的选择,由于这里经过多层异常处理,真正的错误信息隐藏的比较深,如下图: 

看到这儿,相信再遇到这个问题的时候应该会很容易解决了。

时间: 2024-10-08 03:01:48

spring异常被吞的一种情形的相关文章

Spring MVC前端与后端5种ajax交互方式

前端ajax与后端Spring MVC控制器有以下五种数据交互方式.(前台使用了dhtmlxGrid,后端使用了fastjson) 方式一  通过URL传参 通过URL挂接参数,如/auth/getUser?userid='6' 服务器端方法可编写为:getUser(String userid),也可新增其他参数如HttpSession, HttpServletRequest,HttpServletResponse,Mode,ModelAndView等. 方式二  单值传参 前台调用如: aja

spring异常记录-----java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils

今天在练习怎样SSH中进行单元測试的时候出现下列异常: SEVERE: Exception starting filter Struts2 java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:211

windows线程池四种情形(win核心读书笔记)

windows线程池四种情形(win核心读书笔记) Mircosoft从Windows2000引入线程池API,并在Vista后对线程池重新构架,引入新的线程池API.以下所有线程池函数均适用于Vista以后的版本. 用Windows提供的线程池函数有以下几个好处:1,不必要用CreateThread创建线程:2,不必要管理自己线程:3,Windows封装好的线程池,效率高,性能优越. 1 异步方式调用函数 这种方式和我们用CreateThread创建线程的用法差不多,给定一个线程函数模板实现功

spring异常错误信息---

在练习spring项目的过程中,出现了如下异常信息: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:145) at or

Spring事务Transaction配置的五种注入方式详解

Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ??? 总结如下: ??? Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. ???DataSou

Spring基础系列14 -- Spring MVC 请求参数的几种获取方法

Spring MVC 请求参数的几种获取方法 转载:http://www.cnblogs.com/leiOOlei/p/3658147.html 一.      通过@PathVariabl获取路径中的参数 @RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET) public String printMessage1(@PathVariable String id,@PathVariable String n

spring创建连接池的几种方式

spring使用连接池有很多种方式,jdbc(不使用连接池),c3p0,dbcp,jndi,下面将分别贴代码介绍这几种:  1.jdbc方式 使用的是DriverManagerDataSource,DriverManagerDataSource建立连接是只要有连接就新建一个connection,  根本没有连接池的作用 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManag

Spring的依赖注入的2种方式(1天时间)

今天花了一天的时间才调试出来 private      接口   实现类的那个bean; 最后面的那个名字不能随便的写,必须是配置文件中,实现类的那个bean 就是后面的那个名字写错了,花了整整一天 必须有这句注解扫描才能扫描到注解 进行注解的配置,不需要get方法和set方法,小龙儿说xml文件配置才需要set方法 package com.baobaotao1; import org.springframework.context.ApplicationContext; import org.

spring的事务管理有几种方式实现 (转自:http://blog.csdn.net/bopzhou/article/details/7094108)

spring的事务管理有几种方式实现 标签: springhibernate数据库beanlistclass 2011-12-22 09:12 3883人阅读 评论(0) 收藏 举报 Spring+Hibernate的实质: 就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理. 那么再没整合之前Hibernate是如何实现事务管理的呢? 通过Ser