答案: BEA使用的是Catalina,也就是tomcat,无意中发现一个非常隐蔽的也许不算致命的BUG,在JSP中某处的标签如果执行错误,会在前面某处输出缓冲区时无异常退出,而不是在真实错误地点发出错误异常。
10:45 分:却发现FormTag执行异常退出,而且错误日志没有任何输出;所以决定转过去先看看是什么回事。非常奇怪的是,就算在doEndTag中输入断点后,错误日志仍没有输出。最后的检查结果,不是程序有错,而是在某种条件下,tag对output没有响应,所要求输出的vaildatorscript 只输出了一半。
这个tag集成了struts.validator的javascriptStaticTag,不知有没有人这样做:我不想花时间重修把它的代码解剖出来,也不希望让前台的页面多几个需要配置的tag;于是直接用上级的FormTag向它置值,然后直接调用它的doStartTag()——其实,在 JSP容器中不也是这样按注册记录调用它的方法吗?此前偶而发现有这样的错误,不过转眼就恢复正常。既然异常消失,错误日志也没有记录,也就无法发掘它的错误来源了。这次重新出现,引起我的注意,而且错误持续时间比较长,于是可以在程序中设置断点,跟踪它的错误发生的位置。
结果,错误源集中到了不是我写的,来自于struts的validator的这个标签。对于struts这样的中间构件,我现在的态度是如果我不能完看懂它的代码,可以在里面设置断点记录输出到错误日志degbug,就不加采用,所以现在我手中的struts只是有它的构件功能,使用方式与一般所见的struts已经是完全不同了,这也包括了这个javascripStaticTag。对于它的用法,我是希望它作为程序的一部分,当我选定要对某个表单的客户端进行验证时,它自动完成所必需的代码输出,而不需要我手工地设这个TAG,还要匹配它的调用函数名称。这个集成是成功的,已经运行了很长时间,经常了一定强度的测试,但平心而论,对于其中的代码我仍是没有深入。
错误的产生后我打算向缓冲区输出断点,这是由于这个程序是向页面输出validator-rules.xml中的javascript代码,但发现没有成功,许多断点没有输出;表明程序输出是中断的,但输出过程是正常的,否则错误日志会记录下来。进一步的验证表明,程序运行以及从内存记录中获得的 javascript是完整的,从而排除了读取xml发生错误的可能性,而且也证明JAVA程序的运行是完全正常的,错误不在开发者程序,而在于平台本身,在输出缓冲区时无异常退出了!!!由于javascriptTag中是使用stringBuffer最后toString再输出到缓冲区,或者,是由于这个量太大,所以溢出了??于是我把它分成逐段都输出,但结果完全一样。也许是由于我对于它的调用不是由容器进行,直接由parent-TAG调用方法造成缓冲区分配较小??于是改成getString方法,由parent完成输出,可是,结果仍然是一样的。
最后,我打算先越过这一步,看看执行结果如何,发现该页由于BSelectTag由于调关联的BaseIf接口昨晚错删除了一个方法出现异常,于是重新编译后,再执行,结果发现上面的错误消失了。重新恢复这个错误,异常重新出现。这样也就发现了它的原因。事实上,BEA使用的是CATLINAJSP 容器,解释一个JSP页面时是一个统一的过程。这个异常表明,在JSP中前后的输出文本生成是相关联的,位于后面的程序运行错误,象这里,是在后面运行时出现了methodnofound(我估计,因为即使是服务器日志也没有发现错误记录),也令这个解释执行过程中断,造成缓冲区文本输出一半无异常退出。
我很少处理JSP,这是一个经验,如果出现这种缓冲异常输出而程序捕捉不到任何的错误日志时,先把这个页面相关的程序都编译一遍,排除这个可能再说。
这个问题整整花了我两个小时找原因,的确隐蔽,一些副作用是这样就对validator.javascript的代码熟悉了,项目后面有点时间的话,就把它修改一下,只输出这次需要的验证方法script:我总觉得它输出了太多的东西,把validator_rules.xml中的所有 script方法全送出来了。
上一个:在Web应用中图片和长文本的处理策略总结
下一个:优化apache/tomcat配置