接着上一篇讲。

一个异常日志处理的例子:

抛出异常的地方为:

try{

... ...//省略N行

}catch( Exception e){

throw new RuntimeException ("jar文件加载异常!name="+jarFileName, e);

}

打印异常的地方为:

logger.error(e, "类文件加载失败");

这是很正常的手法,打印出堆栈信息,并附加上一些额外信息。

最初,异常堆栈信息是这样的:

(堆栈信息有点多,大家快速往下面看……)

  1. 类文件加载失败
  2. java.lang.RuntimeException: jar文件加载异常!D:\opt\app\WebSphere\output\report\file\loadclass\照片.jar
  3. at com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:123)
  4. at com.proj.report.backmanage.addin.control.ClassLoadController.loadClass(ClassLoadController.java:41)
  5. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  6. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  7. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  8. at java.lang.reflect.Method.invoke(Method.java:597)
  9. at org.zollty.framework.mvc.support.HandlerMetaInfo.invokeMethod(HandlerMetaInfo.java:34)
  10. at org.zollty.framework.mvc.handler.support.ControllerHandler.invoke(ControllerHandler.java:60)
  11. at org.zollty.framework.mvc.handler.support.HandlerChainImpl.doNext(HandlerChainImpl.java:50)
  12. at com.proj.report.backmanage.interceptor.AccessRightInterceptor.dispose(AccessRightInterceptor.java:62)
  13. at sun.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
  14. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  15. at java.lang.reflect.Method.invoke(Method.java:597)
  16. at org.zollty.framework.mvc.support.HandlerMetaInfo.invokeMethod(HandlerMetaInfo.java:34)
  17. at org.zollty.framework.mvc.handler.support.InterceptorHandler.invoke(InterceptorHandler.java:58)
  18. at org.zollty.framework.mvc.handler.support.HandlerChainImpl.doNext(HandlerChainImpl.java:50)
  19. at com.proj.report.backmanage.interceptor.AdminRightInterceptor.dispose(AdminRightInterceptor.java:56)
  20. at sun.reflect.GeneratedMethodAccessor42.invoke(Unknown Source)
  21. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  22. at java.lang.reflect.Method.invoke(Method.java:597)
  23. at org.zollty.framework.mvc.support.HandlerMetaInfo.invokeMethod(HandlerMetaInfo.java:34)
  24. at org.zollty.framework.mvc.handler.support.InterceptorHandler.invoke(InterceptorHandler.java:58)
  25. at org.zollty.framework.mvc.handler.support.HandlerChainImpl.doNext(HandlerChainImpl.java:50)
  26. at org.zollty.framework.mvc.servlet.DispatcherController.handleRequest(DispatcherController.java:52)
  27. at org.zollty.framework.mvc.DispatcherServlet.dispatcher(DispatcherServlet.java:69)
  28. at org.zollty.framework.mvc.DispatcherServlet.doPost(DispatcherServlet.java:33)
  29. at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
  30. at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  31. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
  32. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  33. at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
  34. at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
  35. at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
  36. at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
  37. at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
  38. at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
  39. at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
  40. at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
  41. at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
  42. at java.lang.Thread.run(Thread.java:619)
  43. Caused by: java.util.zip.ZipException: error in opening zip file
  44. at java.util.zip.ZipFile.open(Native Method)
  45. at java.util.zip.ZipFile.(ZipFile.java:114)
  46. at java.util.jar.JarFile.(JarFile.java:133)
  47. at java.util.jar.JarFile.(JarFile.java:70)
  48. at com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:120)
  49. ... 39 more

这是一个很简单的报错,但是堆栈却是一大堆,让人茫然。其实,我想说的是,这个堆栈信息还算少的,在Websphere下,报错信息还要多,我们的错误日志文件,通常都是1分钟几M甚至几十M,我下载的日志文件有800多M的。

经过我对很多日志文件的分析,发现其中90%的报错信息是冗余的。

经过我对异常的特殊处理,现在错误日志变成了如下形式:

16:07:59,415 ERROR ClassLoadController:29 - 类文件加载失败 |- java.lang.RuntimeException: jar文件加载异常!D:\opt\app\WebSphere\output\report\file\loadclass\照片.jar

at com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:123)

at com.proj.report.backmanage.addin.control.ClassLoadController.loadClass(ClassLoadController.java:41)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

... 6 more

at com.proj.report.backmanage.interceptor.AccessRightInterceptor.dispose(AccessRightInterceptor.java:62)

... 6 more

at com.proj.report.backmanage.interceptor.AdminRightInterceptor.dispose(AdminRightInterceptor.java:56)

... 23 more

Caused by: java.util.zip.ZipException: error in opening zip file

at java.util.zip.ZipFile.open(Native Method)

at java.util.zip.ZipFile.(ZipFile.java:114)

at java.util.jar.JarFile.(JarFile.java:133)

... 1 more

at com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:120)

... 39 more

注意看,上面的错误日志少了很多,某些地方用“... 6 more”“... 23 more”代替了。

这样精简之后,对于错误的定位就清晰多了。

例如,我来分析一下上面的日志:

1)首先,读它的错误信息:

类文件加载失败 |- java.lang.RuntimeException: jar文件加载异常!D:\opt\app\WebSphere\output\report\file\loadclass\照片.jar

我了解错误的概况“类文件加载失败了”,进一步原因是“照片.jar这个jar文件加载异常”

2)再看紧跟着错误信息的下面三行错误经过的类路径:

com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:123)

at com.proj.report.backmanage.addin.control.ClassLoadController.loadClass(ClassLoadController.java:41)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

从这三行数据,我得知,这个异常信息是从ClassLoaderUtils.loadJar(ClassLoaderUtils.java:123)这个地方被new出来的。可以猜测,这个地方有如下一个语句:throw new RuntimeException()。又根据下面有Caused by: java.util.zip.ZipException语句,所以断定,真正的写法是throw new RuntimeException(e),其中这个e的类型是java.util.zip.ZipException。

在这之后的数据,是程序调用的轨迹,大概就是经过Http进入到了拦截器和Servlet,进而到了Action(Controller),我只记录了一些核心的轨迹信息。一般来说,这些轨迹信息是毫无用处的。你甚至可以全部去掉。只保留项目包名“com.proj.report.*”开头的信息即可。

再看Caused by语句,这个才是错误的真正原始出处,可以看到,是

java.util.zip.ZipException: error in opening zip file

at java.util.zip.ZipFile.open(Native Method)

也就是说,最底层、最源头的错误,是从ZipFile.open(Native Method)里面new出来的。错误信息是:error in opening zip file

再接着往后面看,看到了最后,是:

com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:120)

... 39 more

这代表,在我们自己写的程序中,错误的最源头是

ClassLoaderUtils.loadJar(ClassLoaderUtils.java:120)

是从这个工具类的第120行抛出来的。

那么,完整的错误轨迹,错误的原因和错误出处,我们都是非常清楚了。而且,根据上面信息,我还可以分析出程序调用的轨迹:(一般来说,没必要,用处不大)

经过上层程序的层层调用,到达了:

ClassLoadController.loadClass(xx)

然后调用了:

ClassLoaderUtils.loadJar(xx)

在这个方法中的如下之处:

ClassLoaderUtils.loadJar(ClassLoaderUtils.java:120)

即120行,抛出了错误信息。

这就是核心的程序运行轨迹,至于loadClass之上的轨迹和loadJar之后的轨迹,是其他API的运行轨迹,属于我们无法控制的范围,故打印出来意义不大。当然,我写的这个异常处理工具,是可以设定的,例如,如果你想看看SpringAPI的运行轨迹,你可以在不排除它的包名,比如org.springframework.mvc。

这样还不够,我还写了一个更强大的工具:ExceptionWrapper,重写了Throwable的方法。从底层去改造异常信息。说实话,SUN JDK里面的那个Throwable设计得并不好,之前我一直在IBM JDK上做测试,没发现问题,换到SUN JDK就出问题了。详见我写的一篇文章介绍:

http://www.cnblogs.com/zollty/p/3396252.html

像Open JDK 和GUN JDK,都是改进过的。我写的这个ExceptionWrapper,可以替代JDK自带的RuntimeException使用。功能更强大。以后我会专门写一篇文章来介绍这个工具。

用ExceptionWrapper包装后,最终的错误堆栈信息为:

类文件加载失败 |- jar文件加载异常!D:\opt\was\file\loadclass\照片.jar

Caused by: java.util.zip.ZipException: error in opening zip file

at java.util.zip.ZipFile.open(Native Method)

at java.util.zip.ZipFile.(ZipFile.java:114)

at java.util.jar.JarFile.(JarFile.java:133)

... 1 more

at com.proj.report.common.util.ClassLoaderUtils.loadJar(ClassLoaderUtils.java:122)

at com.proj.report.backmanage.addin.control.ClassLoadController.loadClass(ClassLoadController.java:41)

... 7 more

at com.proj.report.backmanage.interceptor.AccessRightInterceptor.dispose(AccessRightInterceptor.java:62)

... 7 more

at com.proj.report.backmanage.interceptor.AdminRightInterceptor.dispose(AdminRightInterceptor.java:56)

这样,我满意了。从上面的堆栈信息中,我能很清晰的看到错误的原因和报错的地方,以及程序运行的轨迹,几乎接近完美。

Java异常处理设计(三)的更多相关文章

  1. Java异常处理设计(一)

    很多次的经验教训,让我不得不重视异常处理.经常遇到的问题如下:1)日志不准确,错误原因难以查明!!2)日志量太大,查找麻烦!!3)哪里需要记录日志,哪里不用记录日志?往往随心所欲!!分析以上问题,深入 ...

  2. Java异常处理设计(二)

    考虑对JDK的底层堆栈信息进行处理,一种是重写JDK的Throwable,另一种是在原错误堆栈信息上进行“二次加工”.目前这两种方式我都实现了,效果非常好. 这篇文章主要记录对错误堆栈进行“二次加工” ...

  3. Java异常处理和设计

    在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...

  4. Java异常处理和设计【转】

    Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...

  5. java异常处理的设计

    有一句这样话:一个衡量Java设计师水平和开发团队纪律性的好方法就是读读他们应用程序里的异常处理代码. 本文主要讨论开发Java程序时,如何设计异常处理的代码,如何时抛异常,捕获到了怎么处理,而不是讲 ...

  6. 【Java面试】TCP协议为什么要设计三次握手?

    一个工作5年的粉丝,最近去面试了很多公司,每次都被各种技术原理题问得语无伦次. 由于找了快1个月时间的工作,有点焦虑,来向我求助. 我能做的只是保证每天更新一个面试题,然后问他印象最深刻的一个面试题是 ...

  7. JAVA 异常处理机制

    主要讲述几点: 一.异常的简介 二.异常处理流程 三.运行时异常和非运行时异常 四.throws和throw关键字 一.异常简介 异常处理是在程序运行之中出现的情况,例如除数为零.异常类(Except ...

  8. Java提高篇——Java 异常处理

    异常的概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error:如果你用Syst ...

  9. java异常处理机制

    本文从Java异常最基本的概念.语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Spring的异常处理框 架,阐述了异常处理的基本原则.并且作者提出了自己处理一个大型应用系统 ...

随机推荐

  1. Python设计模式 - UML - 用例图(Use Case Diagram)

    简介 用例图主要是从用户的角度出发对软件产品的功能及执行者进行描述的. 用例图是从需求分析到软件交付的第一步,图示化展示参与者与参与者之间.参与者与用例之间.用例与用例之间的关系,帮助开发人员更好的理 ...

  2. $nextTick 的作用

    文档:深入响应式原理 Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新. $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据 ...

  3. Django的rest_framework认证组件之局部设置源码解析

    前言: Django的rest_framework组件的功能很强大,今天来我来给大家剖析一下认证组件 下面进入正文分析,我们从视图开始,一步一步来剖析认证组件 1.进入urls文件 url(r'^lo ...

  4. python shell的交互模式和文本编辑模式

    之前学python的时候,是拿<笨办法学python>练习的. 书里面基本都是以.py文件去写代码,也就是文本编辑模式. 而交互模式(也就是powershell),唯有在input用户输入 ...

  5. Poiji:基于列名绑定方式将Excel单元行转换为JavaBean的开源框架

    公司的日常事务中经常需要使用excel进行数据汇总,导入导出进行归类统计分析. 因为没有广泛流行的单元行到类转换/属性绑定工具,在功能开发之初或者很长一段时间内, 业务系统中我们处理普通excel数据 ...

  6. 通过github安装crawley出现的问题

    http://www.cnblogs.com/hbwxcw/p/7086188.html

  7. c#Dapper 批量插入Mysql

    <connectionStrings> <add name="sqlconnectionString" connectionString="server ...

  8. 30.Mysql常见问题和应用技巧

    30.Mysql常见问题和应用技巧30.1 忘记Mysql的root密码30.2 如何处理MyISAM存储引擎的表损坏 30.2.1 方法一:使用myisamchk工具 30.2.2 方法二:使用SQ ...

  9. Fefora 14 源

    默认的源不能用,需要用下边的源路径. [fedora] name=Fedora $releasever - $basearch failovermethod=priority #baseurl=htt ...

  10. error while loading shared libraries的解決方法

    我是在启动nginx的时候报这个错误,搜索这个错误时发现这篇文章,非本人(小渡博客)原创. 原文地址:http://blog.csdn.net/dumeifang/article/details/29 ...