关于nest exception

问题:

使用spring经常会遇到类似的问题 

error create bean name xxx failed nest exception class not found... 

想知道是由于前面创建的错误导致后边的异常,还是后边的异常导致前面的创建错误,nest exception(嵌套异常)的真正含义是什么?


回答:

重新贴一下 格式化的, 
1、伪代码代码示例 

Java代码   收藏代码
  1. action {//表现层  
  2.     
  3.    save() {  
  4.        service.save();  
  5.    }  
  6.    
  7. }  


service {//服务层  该层一般会由spring进行动态代理 如完成事务处理 

Java代码   收藏代码
  1. save() {  
  2.     dao.save();  
  3. }  



Java代码   收藏代码
  1. dao {//数据访问层  
  2.      save() {  
  3.         //调用如Hibernate访问数据库,,此时假设数据库没有打开将会抛出 无法建立连接的异常  
  4.      }  
  5. }  



即调用顺序是 action--->service--->dao---->hibernate--->jdbc 

抛出异常顺序是 jdbc---->hibernate---->dao--抛出-->service--继续抛出-->action 


具体异常如下所示: 
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is 

org.hibernate.exception.GenericJDBCException: Cannot open connection         3、service接到异常,因为我集成了spring事务管理切面,因此spring对异常进行封装 
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
at $Proxy4.countAll(Unknown Source) 
at cn.javass.budget.sample.web.action.SampleAction.toList(SampleAction.java:42) 
at cn.javass.budget.sample.web.action.SampleAction.execute(SampleAction.java:33) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452) 
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254) 
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263) 
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248) 
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52) 
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485) 
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) 
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at cn.javass.common.web.filter.SetCurrentURLAndContextPathFilter.doFilter(SetCurrentURLAndContextPathFilter.java:55)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) 
at java.lang.Thread.run(Unknown Source) 
Caused by: org.hibernate.exception.GenericJDBCException: Cannot open connection                 2、此时hibernate将jdbc异常进行封装 抛出无法打开链接 
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52) 
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449) 
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167) 
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160) 
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81) 
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473) 
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
... 78 more 
Caused by: java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection  1、首先jdbc抛出无法建立连接 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:255) 
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:387) 
at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:414) 
at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:165) 
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35) 
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801) 
at java.sql.DriverManager.getConnection(Unknown Source) 
at java.sql.DriverManager.getConnection(Unknown Source) 
at org.logicalcobwebs.proxool.DefaultConnectionBuilder.buildConnection(DefaultConnectionBuilder.java:39) 
at org.logicalcobwebs.proxool.Prototyper.buildConnection(Prototyper.java:159) 
at org.logicalcobwebs.proxool.ConnectionPool.getConnection(ConnectionPool.java:211) 
at org.logicalcobwebs.proxool.ProxoolDataSource.getConnection(ProxoolDataSource.java:97) 
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) 
... 83 more 



也就是说异常其实是栈调用的快照 
1、最下层的异常是出错的原因,上边的异常是对下边的封装,目的是一致性 和 更可读; (即下边异常是引起上边异常的原因,每一个Exception 都有一个couse,如hibernate异常的couse就是jdbc的异常) 
2、对于每一段异常,方法调用顺序是从下往上; 


你的困惑是service处的异常 
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection  

1、想知道是由于前面创建的错误导致后边的异常,还是后边的异常导致前面的创建错误, 
       后边导致前面,,,前面对后面的进行了封装,,目的是提供一致的异常(并且把原始错误显示出来 就是 nested exception 后边部分) 

2、nest exception(嵌套异常)的真正含义是什么? 
     这个是spring实现的,首先我们看一下NestedRuntimeException 

   
Java代码   收藏代码
  1. public abstract class NestedRuntimeException extends RuntimeException {  
  2.   
  3.     /** Use serialVersionUID from Spring 1.2 for interoperability */  
  4.     private static final long serialVersionUID = 5439915454935047936L;  
  5.   
  6.     static {  
  7.         // Eagerly load the NestedExceptionUtils class to avoid classloader deadlock  
  8.         // issues on OSGi when calling getMessage(). Reported by Don Brown; SPR-5607.  
  9.         NestedExceptionUtils.class.getName();  
  10.     }  
  11.   
  12.   
  13.     /** 
  14.      * Construct a NestedRuntimeException with the specified detail message. 
  15.      * @param msg the detail message 
  16.      */  
  17.     public NestedRuntimeException(String msg) {  
  18.         super(msg);  
  19.     }  
  20.   
  21.     /** 
  22.      * Construct a NestedRuntimeException with the specified detail message 
  23.      * and nested exception. 
  24.      * @param msg the detail message 
  25.      * @param cause the nested exception 
  26.      */  
  27.     public NestedRuntimeException(String msg, Throwable cause) {  
  28.         super(msg, cause);  
  29.     }  
  30.   
  31.   
  32.     /** 
  33.      * Return the detail message, including the message from the nested exception 
  34.      * if there is one. 
  35.      */  
  36.     @Override  
  37.     public String getMessage() {  
  38.         return NestedExceptionUtils.buildMessage(super.getMessage(), getCause());  
  39.     }  
  40.   
  41.         ……  
  42. }  


NestedExceptionUtils 工具类 
       
Java代码   收藏代码
  1. public static String buildMessage(String message, Throwable cause) {  
  2.         if (cause != null) {  
  3.             StringBuilder sb = new StringBuilder();  
  4.             if (message != null) {  
  5.                 sb.append(message).append("; ");  
  6.             }  
  7.             sb.append("nested exception is ").append(cause);   
  8.             return sb.toString();  
  9.         }  
  10.         else {  
  11.             return message;  
  12.         }  
  13.     }  

//此处可以看出是异常消息当前异常的错误信息 append上 cause 


Spring总共提供了两种嵌套异常的抽象类 
NestedCheckedException  ----> 受查的嵌套异常 
NestedRuntimeException  ----> 非受查的嵌套异常 

来看一下 NestedRuntimeException  javadoc描述 
Handy class for wrapping runtime Exceptions with a root cause. 
用root couse(就是真正的异常,如之上的hibernate异常  spring包装它)包装运行时异常的一个脚手架类。 

This class is abstract to force the programmer to extend the class. getMessage will include nested exception information; printStackTrace and other like 

methods will delegate to the wrapped exception, if any. 
这个类是抽象的 强制程序员去继承它。getMessage方法将包含嵌套的异常信息(如之前的hibernate异常);printStackTrace 和其他的方法 将委托给包装的异常(如果存在)。 
也就是说这个嵌套异常 做的最重要的工作就是修改了getMessage方法的行为,打印当前异常信息并且把包装的异常通过在 [nested exception is ]之后打印,,其他行为直接委托给原始异常。 


在spring中继承NestedRuntimeException异常的有 
AopConfigException, AopInvocationException, BeansException, BshScriptUtils.BshExecutionException, ConversionException, DataAccessException, 

EjbAccessException, HandlerMethodInvocationException, HttpMessageConversionException, JmsException, JmxException, JndiLookupFailureException, 

JobMethodInvocationFailedException, JRubyScriptUtils.JRubyExecutionException, MailException, MultipartException, RemoteAccessException, RestClientException, 

SchedulingException, ScriptCompilationException, SerializationFailedException, TransactionException, XmlMappingException 

我们最熟悉的就是 DataAccessException  ----> 这个是spring为dao层提供的一致的异常体系,建议去看一下spring官方文档; 

因此 nest exception(嵌套异常)的真正含义是什么? 
   就是spring中又做了一个一致的异常体系,目的是除了打印spring自己的异常信息 还将包装的异常 在 [nested exception is ] 之后显示出来。 

你可能感兴趣的:(java)