免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4030 | 回复: 0
打印 上一主题 下一主题

[WebSphere] 再谈WebSphere的类加载和故障排查 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-19 13:07 |只看该作者 |倒序浏览
再谈WebSphere的类加载和故障排查



今天再次整理了IBM developerworks里有参考价值的文章,希望在遇到ClassCastException、ClassNotFoundException、NoClassDefFoundException、UnsatisfiedLinkError的错误时提供解决思路。

《IBM WebSphere 开发者技术期刊: 类路径冲突的鉴别》一文描述了应用迁移过程中所发生的“故障”,打引号那是因为WAS并没有发出ClassNotFoundException、NoClassDefFoundException等的错误信息,而是“并非预期中的表现”。最终排查的结果是:

其结果是 C:/Program Files/IBM/WebSphere Studio/Application Developer/v5.1.1/runtimes/base_v51/lib/jython.jar ,而不是我们期望的 WEB-INF/lib/jakarta-oro-2.0.7.jar 。

这是一个很典型的类加载错误例子,默认的PARENT_FIRST加载模式让类加载器从应用程序 类装入器中先加载了jython.jar(正好有需要的同名类),而不是Web 模块类装入器里正确的jakarta-oro-2.0.7.jar。解决的方法可以启用PARENT_LAST 加载模式即可。文章中检测类加载路径的Servelet可以作为参考,不过我觉得一般会用-verbose 命令行选项打开 IBM JVM 的详细输出、trace某个确定类的情况或者dump的方法找到类加载路径。

调试方法
《类装入问题解密,第 1 部分: 类装入和调试工具介绍》 介绍了这三种方法



可以用 -verbose 命令行选项打开 IBM JVM 的详细输出。当某些事件发生的时候(例如,类装入时),详细输出会在控制台上显示信息。要想得到额外的类装入信息,可以用详细类输出。可以用 -verbose:class 选项启动这个模式。

解释详细输出
详细输出列出已经打开的所有 JAR 文件,包括到这些 JAR 的完整路径。下面是一个示例:

...
[Opened D:\jre\lib\core.jar in 10 ms]
[Opened D:\jre\lib\graphics.jar in 10 ms]
...所有装入的类都已经列出,同时还指出它们是从哪个 JAR 文件或目录装入的。例如:

...
[Loaded java.lang.NoClassDefFoundError from D:\jre\lib\core.jar]
[Loaded java.lang.Class from D:\jre\lib\core.jar]
[Loaded java.lang.Object from D:\jre\lib\core.jar]
...

可以仅输出某个特定的类加载情况,剔除无关紧要的类:

-Dibm.cl.verbose=<class name>。可以用正则表达式声明类的名称,例如 Hello* 会跟踪所有以 Hello 开头的名称。

更准确的就是用trace工具来跟踪java代码



IBM JVM 有一个内置的方法跟踪工具。这样,不需要修改 Java 代码,就可以跟踪任何 Java 代码(包括核心系统)中的方法。因为这个工具可以提供大量数据,所以可以控制跟踪的级别,只获取需要的信息。

比较常用的步骤是

1.在控制台导航树中单击故障诊断 > 记录和跟踪,然后单击服务器 > 诊断跟踪。
2.单击配置。
3.选中启用记录复选框启用跟踪,清除此复选框禁用跟踪。
…………

1.
1.在控制台导航树中单击故障诊断 > 记录和跟踪。
2.选择服务器名。
3.单击更改日志级别详细信息。
4.如果已启用所有组件,那么可能要关闭它,然后启用特定组件。
5.单击组件或组名。要获取更多详细信息,请参阅日志级别设置 。 如果所选服务器未在运行,您将无法以图形方式查看个人组件。
6.在跟踪字符串框中输入跟踪字符串。
7.选择应用,然后选择确定。
要输入跟踪字符串以将跟踪规范设置为需要的状态:

亦可以在故障诊断 > 类装入器查看器 以访问企业应用程序拓扑页。

在“类装入器查看器”页中,单击搜索以访问搜索页,在该页面上,可以在类装入器中搜索下列内容:

特定字符串
特定 .jar 文件
特定目录中的文件名
特定类装入器装入的文件名
搜索区分大小写

用Trace来跟踪应用程序情况其实是很有技术含量的活,能自成一章。我接触的项目基本到了这一层都是由开发人员去找BUG,所以实践比较少,没有分享的心得。有机会的话我以后学习学习再写。

如果你觉得用trace来跟踪调试比较复杂,那么可以直接生成一个javacore文件,里面会记录类装入器信息。推荐用wsadmin命令来生成core文件,因为kill -3带出个heapdump可就不好玩了。

键入wsadmin.bat命令,进入wsadmin管理命令行,键入如下代码:

set jvm [$AdminControl completeObjectName type=JVM,process=server1,*]
$AdminControl invoke $jvm dumpThreads

javacore.TIMESTAMP.NUMBER.txt  文件会自动在C:\WebSphere\AppServer或C:\WebSphere\AppServer\default\或您指定的目录中产生。

解决问题
了解了查找的方法,那么就可以开始解决问题:《类装入问题解密,第 2 部分: 基本的类装入异常》



ClassNotFoundException 是最常见的类装入异常类型。它发生在装入阶段。Java 规范对 ClassNotFoundException 的描述是这样的:

当应用程序试图通过类的字符串名称,使用以下三种方法装入类,但却找不到指定名称的类定义时抛出该异常。

类 Class 中的 forName() 方法。
类 ClassLoader 中的 findSystemClass() 方法。
类 ClassLoader 中的 loadClass() 方法。
所以,如果显式地装入类的尝试失败,那么就抛出 ClassNotFoundException。

通过抛出 ClassNotFoundException,类装入器提示,定义类时所需要的字节码在类装入器所查找的位置上不存在。这些异常修复起来通常比较简单。可以用 IBM 的 verbose 选项检查类路径,确保使用的类路径设置正确。如果类路径设置正确,但是仍然看到这个错误,那么就是需要的类在类路径中不存在。要修复这个问题,可以把类移动到类路径中指定的目录或 JAR 文件中,或者把类所在的位置添加到类路径中。

更多的解决方法请看原文,第三第四部分的《类装入问题解密,第 3 部分: 处理更少见的类装入问题》、

《类装入问题解密,第 4 部分: 死锁和约束》就当扩展阅读好了。

个人感想
类加载问题是一个不难解决却又令人头疼的问题,特别当多个应用部署在一起的时候。问题状况相似,其实出错的原因并不相同,往往单独成功的例子——例如jar包换个目录,对于另一个环境却束手无策。网上有不少的“解决案例”就是这种情况,所以我把“渔”的方法整理在这里,并非个人原创,都是照搬IBM developerworks已有的内容。惭愧之余,也感叹一下IBM的强大。其它的大型厂商,Oracle是需要Metelink帐号才能看到最有用的资料;SAP也需要购买产品后才能查看详细文档,否则就是简陋两字;Microsoft的KB和webcasting做的很好,但是本地化和有价值的文章却逊一筹。在都想依靠服务赚钱的现在,IBM没有把这些资料敝帚自珍,让我们有个学习交流的环境,这也许是它数十年它经久不衰的奥秘之一吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP