Search code examples
javaibm-midrangerpg

Calling a remote Java program on iSeries from RPG


I'm looking to invoke a Java program from RPG running on Iseries V5r4. The remote program is a web service client (performing a postcode lookup), running in Websphere.

Ideally I'd like to call it direct from RPG? is that possible? or do I have to create a java program to run on the iSeries and use RMI or something to call the remote java program.

We aren't keen on calling the extenral webservice direct as it means opening path from otherside world direct to iSeries.

I'm not an RPG programmer, just looking for something to point our guys in the right direction or anything I need to enable to make the java programs more consumable for the RPG folks.

Thanks, Scott


Solution

  • Since the program is running on a remote server, you can't call it directly from RPG. Given that it's a web service, I would create a Java program to run on the iSeries and call that Java program from within RPG. Nowaday's, RPG can interface directly with Java. You have to create some D-specs to declare the class and prototype out the method calls. In the following example, assume a Java class exists called ServiceCaller in the package 'tools'. It has a single method called getServiceReply which accepts three character fields and returns an integer.

     *Define the Java class locally.                                       
    DServiceCaller    S               O   CLASS(*JAVA:'tools.ServiceCaller')
    
     *Class constructor.  No parameters.                                   
    DnewServiceCaller PR              O   EXTPROC(*JAVA:                   
    D                                       'tools.ServiceCaller':          
    D                                       *CONSTRUCTOR)                  
    D                                     CLASS(*JAVA:'tools.ServiceCaller')
    
     *GetServiceReply.
     *public int getServiceReply(byte[] parm1, byte[] parm2, byte[] parm3)
    DgetServiceReply  PR            10I 0 EXTPROC(*JAVA:
    D                                       'tools.ServiceCaller':
    D                                       'getServiceReply')
    D Parm1                        400A   CONST
    D Parm2                        400A   CONST
    D Parm3                        400A   CONST
    

    Your RPG calc specs will look something like this free-form example:

    /free
      ServiceCaller = newServiceCaller();
      iReply = getServiceReply(ServiceCaller:'Parm1':'Parm2':'Parm3');
    /end-free
    

    Inside the java code, within the getServiceReply method, convert those byte arrays to strings like this:

    sParm1 = new String(parm1);
    sParm2 = new String(parm2);
    sParm3 = new String(parm3);
    

    Granted, this is an oversimplified example and your application needs will be slightly different. You will want to add error handling code in case the web service doesn't reply. You may also want to use getters and setters in your class. It all depends on your application needs and the requirements of the remote web service.

    Some notes on RPG types to Java types:

    RPG Type      Java Type
    10I 0         int
     3I 0         byte
     5I 0         short
    20I 0         long
      N           boolean
      A           byte[]
    

    If you are feeling particularly ambitious, you can call the native Java HTTP classes from within your RPG. But I've found that a custom Java program to act as an in-between that is written specifically to talk to RPG is an easier way to go. Although RPG can talk to Java, it's not as pretty as Java talking to Java.

    Additional information on calling Java from RPG can be found in the ILE RPG Programmer's guide. The V5R4 version can be found here: http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/books/sc092507.pdf