trycatch无法捕获编译错误

问题描述

开发人员漏提交Java代码,测试人员在编辑器报错的情况下仍然进行打包操作,部署到was上运行时报错。

报错信息

webapp E com.ibm.ws.webcontainer.webapp.WebApp logError SRVE0293E: [Servlet Error]-[null]: com.ibm.ws.webcontainer.webapp.WebAppErrorReport:
at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:624)
at com.ibm.ws.webcontainer.srt.SRTServletResponse.sendError(SRTServletResponse.java:1071)
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:770)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:505)

错误分析

问题根本原因

首先,在代码的最外层,已经添加了全部的异常捕获;发生这种捕获失败的情形,目前发现的可能原因:

  1. 编译class的Java源文件存在问题(这个是本文要讨论的问题)
  2. 存在class冲突,例如项目中引入不同版本的jar,中间件的class加载顺序决定是否会出现问题;可以参考:was设置共享库解决jar冲突

日志报错分析

was的报错关键信息是WebApp,说明它是应用端自身的一个error。不过奇怪的是,那一行既然报错了,但是为什么没有被外层的try-catch捕获呢?
这个说明try-catch捕获的力度不够,错误的等级比Exception还要高,也就是说要用Throwable错误(throwable和Exception的区别)

代码测试

// 常量类
Public class Constant{
	Public class Payment{
		public static final String HMCX = "00";
	}
}
// 运行的类
public void test(){
	System.out.printLn("开始");
	try{
		String code = Constant.Payment.HMCX;
		System.out.printLn(code);
	}catch(Exception e){
		System.out.printLn("异常");
	}
	System.out.printLn("结束");
}
// 注释掉常量后,在编译器报错的情况下,仍然加载运行类反编译后的结果
public void test(){
	throw new Error("Unresolved compilation problem: HMCX annot be resolved or is not a field");
}
// 增加Throwable 捕获
try{
	test();
}catch(Exception e){
	System.out.printLn("异常");
}catch(Throwable t){
	// 如果在test方法存在编译错误的情况,会进入到该方法
	System.out.printLn("无法运行的错误");
}

部署在Tomcat情形

将上面同样有问题的代码,部署在Tomcat服务器,只会报404,可是服务器没有任何日志输出。项目是ssh框架的(比较古老),通过debug模式,发现在如下struts框架的类的异常中进行了处理。

// org.apache.struts.xwork.xwork-core
// com.opensymphony.xwork2.DefaultActionInvocation.class
protected String invokeAction(){
	...
	try{
		...
	}catch(InvocationTargetException e){
		Throwable t = e.getTargetException();
		...
	}
}

由于所有的请求都是访问xwork2.ActionSupport的实现类,也可以看出Struts2框架是通过反射进行调用实现ActionSupport的类。

你可能感兴趣的:(中间件,Java)