我的目标是从Java调用Web服务,该服务是从RPG函数启动的。(我知道,还有很长的路要走,但这正是我们需要的)
我在AS400上创建了一个/JavaLib
文件夹,并复制了我们需要的所有外部Jar。
使用静态方法WebServiceCaller.Call()
创建一个Java类来调用Web服务。当我运行我的RPG程序时,RPG调用这个方法一切都很好。
我得到一个Java异常:
消息……:调用Java方法时收到Java异常(C G DF)
原因…..:程序WAL6036/WEBSERCALR中的RPG过程WEBSERCALR收到Java异常"Java.lang.NoClassDefFoundError:
调用带有签名的方法"Call"时出现"javax.xml.rpc.ServiceException"类中的"(LwebService.Input;)LwebService.Output;"
"webService.WebServiceCaller".
CLASSPATH变量:
/JavaLib:/home/WAL60326/WebServiceCaller
所以我相信我的RPG和Java类很好,我相信我已经正确地设置了CLASSPATH变量。不确定还有什么需要检查的。
更新
所以我需要的jar文件是我检查过的jaxrpc.jar
;它确实存在于我的CCD_ 4中。能够在AS400 java version "1.5.0"
上检查我的Java版本。按照以下说明检查我的操作系统是否为V6R1。
可能是我的Java版本过期了,所以要加载/工作这个Jar文件吗?这有可能吗?
编辑
这是我的源代码:
Java:WebServiceCaller.Java
package webService;
import java.rmi.RemoteException;
import stocklistGetBids.GetBidsProxy;
public class WebServiceCaller {
public static Output Call(Input in) { // Input Class, is just a way to hold all the input together
Output out = null; // Output Class, holds all the output together
try {
GetBidsProxy getBidsProxy = new GetBidsProxy(); // GetBidsProxy generated by Eclipse
out = new Output(getBidsProxy.getBids(in.LogKey, in.Id));
} catch (RemoteException e) {
e.printStackTrace();
out = new Output("ERR");
}
return out;
}
}
请注意,GetBidsProxy类是由Eclipse生成的。Java端在我的Windows机器上运行良好。只是AS400机器上没有。
RPG:websercarr.RPGLE
H DFTACTGRP(*NO)
H thread(*serialize)
D WebsercalInput DS
D ReturnCode 7A
D LogKey 20A
D ID 20A
D jString S O CLASS(*JAVA:'java.lang.String')
D jLogKey S O CLASS(*JAVA:'java.lang.String')
D jID S O CLASS(*JAVA:'java.lang.String')
D Input S O CLASS(*JAVA:'webService.Input')
D Output S O CLASS(*JAVA:'webService.Output')
D new_Input PR O EXTPROC(*JAVA:
D 'webService.Input':
D *CONSTRUCTOR)
D LogKey like(jString)
D ID like(jString)
D new_String PR O EXTPROC(*JAVA:
D 'java.lang.String':
D *CONSTRUCTOR)
D bytes 30A CONST VARYING
D Call PR like(Output)
D EXTPROC(*JAVA:
D 'webService.WebServiceCaller':
D 'Call')
D STATIC
D in like(Input)
D getReturnStat PR O EXTPROC(*JAVA:
D 'webService.Output':
D 'getReturnedStatus')
D CLASS(*JAVA:'java.lang.String')
D getBytes PR 65535A VARYING
D EXTPROC(*JAVA:
D 'java.lang.String':
D 'getBytes')
C *ENTRY PLIST
C PARM WebsercalInput
/free
jLogKey = new_String(LogKey);
jID = new_String(ID);
Input = new_Input(jLogKey:jID);
Output = Call(Input);
jString = getReturnStat(Output);
ReturnCode = getBytes(jString);
return;
/End-Free
CLASSPATH对于给定作业只读取一次,即第一次调用java命令和JVM启动时。如果您的CLASSPATH在此之后发生更改,JVM将不会看到或使用新的CLASSPATH。注销和打开(开始一个新作业),设置CLASSPATH(我在我的登录程序中这样做),然后尝试使用您正在使用的类。
如果CLASSPATH是正确的,那么另一件需要检查的事情就是RPG程序中的Java原型。它需要与Java类定义完全匹配。
首先,确保您的jaxrpc.jar拥有您认为应该拥有的所有类。启动QShell,然后启动java tf /JavaLib/jaxrpc.jar
。确保你至少有这些:
javax/xml/rpc/Call.class
javax/xml/rpc/ServiceFactory.class
javax/xml/rpc/ServiceException.class
接下来,用纯Java做一个简单的概念验证程序,以确保所有部分都能按预期工作。注意:JAX-RPC已经过时,在Java 1.6及更高版本中已经过时。它已被JAX-WS所取代。如果这是一个全新的应用程序,请考虑使用更新的实现。DeveloperWorks 2006年的这篇文章解释了其中的一些差异。
一旦您编写了一个纯Java程序,就可以使用您使用的Java类并在RPG中对其进行原型化了。假设你已经完成了所有这些,你可以编辑你的问题来显示RPG*CLASS原型和用于调用它们的RPG代码吗。基本上,看看读到这个问题的人是否可以在另一个盒子上重新创建设置。
我在RPG代码中使用了一些Java,发现将容器文件夹添加到CLASSPATH中是不够的。我必须识别CLASSPATH中的各个罐子。