RPGIV编程问题百解(31)CPF5029系统报错分析与处理(1)Java调用RPG
问题:
请教JAVA调用RPG的问题(CPF5029)
本人遇到一个JAVA调用RPG的问题,具体内容如下:
在JAVA的程序A中用IBM提供的包调用AS/400的CLP程序B,CLP程序B会调用以个RPG程序C
A(JAVA)-->B(CLP)-->C(RPG)
在执行到RPG程序C中,有一个CHAIN PF的动作,但是这个时候系统返回了CPF5029 data mapping error on member的错误。之后我用WRKQRY查询了CHAIN操作出错的PF,通过PF KEY定位到了RPG程序C CHAIN的那条记录后,这条记录的所有字段的值都是正常的,并没有error。
这个错误发生后,我直接在AS400端DEBUG CLP程序B,当执行到RPG程序C时,上述错误却没有发生。再次通过JAVA调用,又发生了同样的问题。
不知大家有没有碰到过相同的问题?
我查了一下站内的帖子,有一个帖子所描述CPF5029的问题是因为NULL值引起的,不过我把我的RPG程序改为ALLOW NULL *YES之后,JAVA调用时问题依然存在。
找到了另外一个message ID CPF5035,我看到的error code是22
A shift-out character was found while converting to a single or mixed byte CCSID or a substitution character was found. The data could not be converted.
在JOB LOG中,除了KEY字段之外,在RPG中CHAIN PF的动作中,其中PF的大部分字段有Substitution characters may be used for field,但PF中最后1个字段没有使用substitution character。个人推测问题原因可能是:
1. 最后的几个字段没有使用substitution character,是否因为这样而导致CHAIN操作取出记录之后,因为substitution character不足,所导致取出记录失败。有没有可能对一个JOB的substitution character 数量进行设置?或者通过某种设置而避免
2.在JOB LOG中的Substitution characters may be used for field ,按F1后显示CPI431B,具体信息是Input/output mapping.The I/O field is ISEASN with CCSID836 in format RINVMST.The final CCSID required for the I/O field is 37。是否可能是substitution characters 与 field 之间的CCSID不一样所导致的问题?
找到问题所在了!
公司换了台新的400之后,系统参数QCCSID是65535,所以JAVA连接400的程序JOB的默认CCSID 37,而PF的CCSID是935。CPF5035中的有一句“The data could not be converted"可能就是指935无法转换至37。
不过Delphi程序连接AS/400的 JOB CCSID也是37,却没有产生相同的错误,这点还没有理解。
再去补下CCSID的知识。。。
分析和回答:
passthru
首先,我怀疑楼主的debug方法不对。请看我的blog中文,passthru.cublog.cn,《利用DELAY进行400下程序联调》
从经验上讲,应该是java带入的key值内容与key值的字段属性不符。
ccsid 37与ccsid 935,不会产生冲突的,因为对字段内容,单字节字符用ccsid 37解释;如果pf用ccsid 935,对双字节字符,就有ccsid 935解释。即使,系统ccsid与pf的ccsid不一致,也只是pf中的字段内容出现乱码,不会影响程序操作至系统报错,只会造成程序处理逻辑结果错误。
key值如果是字符型的,java传入的字符串,无论是单字节,还是双字节,还是混合型,都不会报错。但是,如果key是数字型,java若传入的值是字符型,就会报CPF5029。还有种情况,如果key是定义O型,java传入的内容如果是单字节,也会系统报错。
400 RPG有个天生的缺陷:字段属性与内容可以不一致。只有在rpg操作符下,才会系统报错。利用o表except不会报错。
阅读(2946) | 评论(3) | 转发(0) |