问题描述
华为Oracle Agile PLM运行过程中的一个严重平台问题。IBM JDK SR2在AIX 5.3 64位操作系统无法实现Java Reflection,由Jerry Chan在华为PLM故障(无法触发Inbox Notification)的系统分析中率先发现,Oracle开发团队直到6个月后才确认。
问题背景
Agile PLM的Inbox Notification能使Agile User接收各种事件下的业务通知。但是在华为的测试和正式环境中启用该功能后,所有用户均无法接收,即便Email能收到。
系统环境如下:
- OS: AIX 5.3 64bit
- Middleware: Weblogic 10g R3
- JDK: IBM JDK6_64-SR2-pap6460sr2-20080818_01
- App: Agile PLM 9.3.0, 9.3.0.1
Inbox Notification的基本逻辑是由一个定时器从数据库中查找所有满足条件的业务,包装后塞入JMS队列,由Clustering中的任何一台node去consume。但是在华为的问题中,JMS消息队列还没有创建,日志中就出现以下提示:
[21 Aug 2009 15:48:55, GMT+08:00] [ERROR] [ <Inbox Notification Subsystem> Failed to create notification. Notification details : [<Notification parentKey="null" fieldId="18420" Value="se2" Type="0" />, <Notification parentKey="null" fieldId="18419" Value="wanghui se1" Type="0" />, <Notification parentKey="null" fieldId="18423" Value="" Type="0" />, <Notification parentKey="null" fieldId="18421" Value="come" Type="0" />] Reason: Invalid bean property: count, bean class= class com.agile.common.server.notification.NotificationValue]
分析日志
Invalid bean property: count,初步说明NotificationValue的一个count属性无法被识别。反编译NotificationValue,观察源代码如下:
public int getCount() { return count; } // dummy for the DAO. public void setCount(int icount){ count = icount; }
注意在源代码中没有count属性,但是NotificaitonValue是一个Bean,get和set方法均操作了Count,因此可认为Count存在。而在华为的AIX平台,count无法为Inbox Notificaiton模块识别。继续分析。
JMS包装之前,在另一个类中,有如下解析NotificationValue Bean的代码
beanInfo = Introspector.getBeanInfo(beanClass); beanInfoMap.put(beanClass.getName(), beanInfo); ... PropertyDescriptor[] props = beanInfo.getPropertyDescriptors(); PropertyDescriptor pd = null; String propName = Introspector.decapitalize(name) ; for (int i = 0; i < props.length; i++) { if (props[i].getName().equals(propName)) {
这是一段十分诡异的设计方法:数据库保存了NotificationValue的所有属性,再由这个方法通过Java反射(Reflection)来校验类的正确性。初步分析问题出在beanInfo.getPropertyDescriptors()中,该方法无法取得bean的所有属性。因此在equals比较中无法匹配。
查阅IBM SDK
得出上述的初步结论后,将可疑的根源放在IBM SDK6 R2上来。查阅IBM SDK,没有专门针对pap6460sr2-20080818_01版本的BUG列表,但是从如下网址中发现很多严重的BUG
http://www.ibm.com/developerworks/java/jdk/aix/j664/Java6_64.fixes.html
比如以下的BUG均为Java Reflection缺陷,均发生在比pap6460sr2-20080818_01版本高的JDK中,因此,高度怀疑pap6460sr2-20080818_01也拥有如此代码缺陷。
148886 IZ48099 620700130 600 15/04/2009 N/A BEAN INTROSPECTOR RETURNS A BEANINFO BUT WITH WRONG PROPERTY DATA 138191 IZ26930 620700130 600 14/08/2008 N/A INTROSPECTOR.GETBEANINFO() WILL EXCLUDE PUBLIC STATIC METHODS 142733 IZ35551 620700130 600 2008/10/24 N/A Introspector.getBeanInfo() throws exception in certain cases 148881 IZ48098 620700130 600 06/05/2009 N/A BEAN INTROSPECTOR RETURNS DIFFERENT INSTANCES OF CLASS OR METHOD FOR SUB AND SUPER CLASSES 145049 IZ40444 620700130 600 08/01/2009 N/A USING INTROSPECTOR TO GET BEAN INFO THROWS A NULLPOINTEXCEPTION
解决方法
建议华为将Weblogic的 IBM JDK升级为高版本。但华为表示需要经Oracle官方证实。6个月后,Oracle Agile经过分析后,才确认Inbox Notification问题的根本原因JDK6_64-SR2-pap6460sr2-20080818_01的Java Reflection在AIX平台的严重BUG,并提议升级为以下高版本:
JDK6-SR5 pap6460sr5-20090529_04