我们使用com.ibm.as400.data.ProgramCallDocument
类通过Java与iSeries上的RPG程序进行接口。在大多数情况下,对于我们的WebSphere应用程序,我们已经将我们的RPG / Synon程序与CL配合使用,并使用PCML与它们进行接口。我们通常也没有将结构用作输入输出。
这次,我们的一位RPG开发人员在RPG IV(不是Synon)中创建了该程序,并给了我们PCML与该程序的接口。我们有三个inputoutput参数作为常规String。没什么大不了的。我们之前已经做到了。现在,您可以看到的第四个参数是一个计数为100的结构,它是inputoutput。
当我们尝试调用RPG程序时,我们所获得的只是大量的空白(即,十六进制40)。字符串参数恢复正常。但是结构没有。所有的内容都是空白。
当我们让RPG程序员进行验证时,他可以看到他的程序确实返回了结构数组。他还编写了一个快速而肮脏的CL,以确保他的程序确实返回了值,并且他说CL证明确实如此。
所以现在我很困惑。我什至试图找到一种传递值的方法,看看是否有区别。但是无论我是什么使它不满意(因为我与parms列表不匹配),还是只得到空白。对前进的方向有任何想法吗?
这是PCML文件
<pcml version="4.0">
<!-- RPG program: IL010S20 -->
<!-- created: 2010-07-13-11.28.53 -->
<!-- source: CPPGENL/QRPGLESRC(IL010S20) -->
<!-- 2208 -->
<struct name="ADDRINFO">
<data name="PREDIRECTION" type="char" length="2" usage="inherit" />
<data name="STREETNAME" type="char" length="30" usage="inherit" />
<data name="POSTDIRECTION" type="char" length="2" usage="inherit" />
<data name="STREETTYPE" type="char" length="4" usage="inherit" />
<data name="LOWADDRESS" type="char" length="11" usage="inherit" />
<data name="HIGHADDRESS" type="char" length="11" usage="inherit" />
<data name="ODDEVEN" type="char" length="1" usage="inherit" />
<data name="TERRID" type="char" length="2" usage="inherit" />
<data name="TAXCODE" type="char" length="5" usage="inherit" />
<data name="TERRNAME" type="char" length="30" usage="inherit" />
</struct>
<!-- 2226 -->
<program name="program" path="/QSYS.LIB/DEVOBJL.LIB/IL010S20.PGM">
<data name="STATE" type="char" length="2" usage="inputoutput" />
<data name="ZIP" type="char" length="5" usage="inputoutput" />
<data name="STREET" type="char" length="30" usage="inputoutput" />
<data name="RETURNADDR" type="struct" struct="ADDRINFO" count="100" usage="inputoutput" />
</program>
</pcml>
并按如下方式加载ProgramCallDocument:
//sys is our AS400 object and parameters is a HashMap.
ProgramCallDocument newPcml = new ProgramCallDocument( sys, pcmlfileName );
Iterator parametersKeysI = parameters.keySet().iterator();
StringBuffer loggingStatement = new StringBuffer();
while( parametersKeysI.hasNext() ) {
String key = (String)parametersKeysI.next();
if("program.RETURNADDR".equalsIgnoreCase(key)) {
AS400Structure [] structure = (AS400Structure[]) parameters.get(key);
int [] indeces = new int[1];
indeces[0] = 0;
for(int i = 0; i < structure.length; i++) {
indeces[0] = i;
Object paramValue = structure[i];
loggingStatement.append(paramValue).append(", ");
newPcml.setValue(key, indeces, paramValue);
}
}
else {
Object paramValue = parameters.get( key );
loggingStatement.append( paramValue ).append( ", " );
//set the value
newPcml.setValue( key, paramValue );
}
}
然后使用
newPcml.callProgram('program');
调用程序,从中可以看到,调用返回true。但是,当我们去读取结构时,什么也没有。我什至使用com.ibm.as400.data.PcmlMessageLog.setTraceEnabled(true);
尝试查看parms,这使我感到困惑。我们看起来好像没有问题,但是没有得到我们期望的结果。任何帮助或指示,将不胜感激。到目前为止,在线的Javadocs和示例并不是最有用的。
最佳答案
好。这很愚蠢,我们不希望早点检查。但是问题出在我们的字符串/字符上。即使我们的iSeries在键入时几乎处理大写字母,因为我们使用的是jt400.jar,但我相信它会在Java应用程序中读取小写字母并将其字节等效项发送到iSeries中,因此我们没有在数据库中的RPG读取在RPG程序中匹配。我们的iSeries团队刚刚修改了该程序,以将所有出现的内容“提高”,从而解决了这个问题。我们只是认为这是可以的,因为在iSeries上大多数事情是如何自动“移到上层”的。猜猜我们错了。