概述
相信很多初学者都很怕eclipse下满篇通红的异常信息,其实这些异常信息是定位代码问题最好的方法。这篇文章主要记录下我遇到异常堆栈信息时的思路。
JavaSe中没有用专门Log类捕获的异常
如下代码所示:
public class TestException {
public static void main(String[] args) {
new TestException().fun1();
}
public void fun1(){
fun2();
}
public void fun2(){
fun3();
}
public void fun3(){
int [] arr = {1,2};
System.out.println(arr[2]);
}
}
执行后会报IndexOutOfBoundsException异常,异常信息如下所示:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at pers.wayss.allTest.TestException.fun3(TestException.java:19)
at pers.wayss.allTest.TestException.fun2(TestException.java:14)
at pers.wayss.allTest.TestException.fun1(TestException.java:10)
at pers.wayss.allTest.TestException.main(TestException.java:6)
异常信息很明显地显示了错误发生的位置:
1. 在线程“main”发生的异常;
2. 异常类型是Array类型的数组越界;
3. 直接导致发生异常的包名-类名-方法名-代码行数;
4. 调用发生异常的方法的包名-类名-方法名-代码行数;
通过这些信息,便可以迅速定位于解决问题了。
用Log4j产生的日志文件中的异常
首先要说的是,Log4j可以自定义日志的格式,与日志的级别,这里不再讨论Log4j的使用问题。但是,Log4j的日志格式基本都是下面这个样子:
举一个异常例子,HBASE-15966(随便找的):
2016-06-02 20:22:50,771 ERROR [B.DefaultRpcServer.handler=22,queue=2,port=16020] access.SecureBulkLoadEndpoint: Failed to complete bulk load
java.io.FileNotFoundException: File doesn't exist: hdfs://[my cluster]/[my path] at org.apache.hadoop.fs.azure.NativeAzureFileSystem.setPermission(NativeAzureFileSystem.java:2192) at org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint$1.run(SecureBulkLoadEndpoint.java:280) at org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint$1.run(SecureBulkLoadEndpoint.java:270) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:356) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1651) at org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint.secureBulkLoadHFiles(SecureBulkLoadEndpoint.java:270) at org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos$SecureBulkLoadService.callMethod(SecureBulkLoadProtos.java:4631) at org.apache.hadoop.hbase.regionserver.HRegion.execService(HRegion.java:6986) at org.apache.hadoop.hbase.regionserver.HRegionServer.execServiceOnRegion(HRegionServer.java:3456) at org.apache.hadoop.hbase.regionserver.HRegionServer.execService(HRegionServer.java:3438) at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:29998) at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2080) at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:108) at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(RpcExecutor.java:114) at org.apache.hadoop.hbase.ipc.RpcExecutor$1.run(RpcExecutor.java:94) at java.lang.Thread.run(Thread.java:745)
这种日志的看法为:
1. 显示日志记录的时间;
2. 显示日志级别;
3. 打印出改日志的类信息(这个需要在配置文件中配置),说明是什么导致这个问题;
4. 从上往下,依次是什么导致这个问题,谁的调用了导致的,直到线程的run方法;
所以,通过Log4j的日志信息,也很快的定位问题发生的原因与位置。