stevebeech
asked on
Java and PCML?
Hi,
I'm using a Java program with a PCML file to pass and retrieve parameters from a RPG service program, successfully. However, some of the RPG code I'm calling returns a value to indicate whether the program ran successfully or not. I have coded for this in the PCML file program element:
<program name="xx" entrypoint="xx" path="/QSYS.lib/XX.lib/XXX X.srvpgm" returnvalue="integer"/>
and ensured that the returned value is a 4byte integer (as per the PCML spec).
The problem is I can't figure out how to access this value within my Java code.
Can anyone tell me how?
Cheers,
Steve
I'm using a Java program with a PCML file to pass and retrieve parameters from a RPG service program, successfully. However, some of the RPG code I'm calling returns a value to indicate whether the program ran successfully or not. I have coded for this in the PCML file program element:
<program name="xx" entrypoint="xx" path="/QSYS.lib/XX.lib/XXX
and ensured that the returned value is a 4byte integer (as per the PCML spec).
The problem is I can't figure out how to access this value within my Java code.
Can anyone tell me how?
Cheers,
Steve
Are you running this in some way with Runtime.exec? If so, i suspect that the value you're talking about may well be the return value of the process, which of course you can read from waitFor
ASKER
You've lost me.
Here's my code (in case it helps):
public class SystemName {
/** Constructor for the SystemName object */
public SystemName() { }
/**
* Description of the Method
*
*@param argv Description of the Parameter
*/
public static void main(String argv[]) {
// Create and instantiate an AS/400 Object
System.out.println("Connec ting to iSeries...");
AS400 sys = new AS400("XXX001", "username", "password");
// Create Data Objects
ProgramCallDocument pcml;
boolean rc = false;
String name;
// String for returned name value
String msgId;
// String for returned name value
String msgText;
// Strings for as400 messags/400
try {
// Instantiate the Objects (assign the variables)
pcml = new ProgramCallDocument(sys, "CallProgramPcml");
pcml.setValue("GETSYSNAMJ. sysname", new String("xxxxxxxx"));
// Call the Program
rc = pcml.callProgram("GETSYSNA MJ");
// If return code is false, get messages from the iSeries
if (rc == false) {
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("GETSY SNAMJ");
// Loop through all messages and write them to standard output
for (int m = 0; m < msgs.length; m++) {
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("Call to GETSYSNAMJ failed. See messages listed above");
System.exit(0);
}
// Return code was true, call to GetSysNam succeeded - woo-hoo!
else {
// Process the returned Data
name = (String) pcml.getValue("GETSYSNAMJ. sysname");
System.out.print("Returned System Name: " + name);
System.exit(0);
}
} catch (PcmlException e) {
System.out.println(e.getLo calizedMes sage());
e.printStackTrace();
System.out.println("Call to GETSYSNAMJ failed");
System.exit(0);
}
// Disconnect from AS/400
sys.disconnectAllServices( );
}
}
and my PCML file:
<pcml version="3.0">
<program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/ SRV_SYSNM2 .srvpgm" returnvalue="integer">
<data name="sysname" type="char" length="10" usage="inputoutput" init="XXXXXXX"/>
</program>
</pcml>
It's the returnvalue that I want to get at, but it isn't passed as a parameter (like sysname is)
??
Here's my code (in case it helps):
public class SystemName {
/** Constructor for the SystemName object */
public SystemName() { }
/**
* Description of the Method
*
*@param argv Description of the Parameter
*/
public static void main(String argv[]) {
// Create and instantiate an AS/400 Object
System.out.println("Connec
AS400 sys = new AS400("XXX001", "username", "password");
// Create Data Objects
ProgramCallDocument pcml;
boolean rc = false;
String name;
// String for returned name value
String msgId;
// String for returned name value
String msgText;
// Strings for as400 messags/400
try {
// Instantiate the Objects (assign the variables)
pcml = new ProgramCallDocument(sys, "CallProgramPcml");
pcml.setValue("GETSYSNAMJ.
// Call the Program
rc = pcml.callProgram("GETSYSNA
// If return code is false, get messages from the iSeries
if (rc == false) {
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("GETSY
// Loop through all messages and write them to standard output
for (int m = 0; m < msgs.length; m++) {
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("Call to GETSYSNAMJ failed. See messages listed above");
System.exit(0);
}
// Return code was true, call to GetSysNam succeeded - woo-hoo!
else {
// Process the returned Data
name = (String) pcml.getValue("GETSYSNAMJ.
System.out.print("Returned
System.exit(0);
}
} catch (PcmlException e) {
System.out.println(e.getLo
e.printStackTrace();
System.out.println("Call to GETSYSNAMJ failed");
System.exit(0);
}
// Disconnect from AS/400
sys.disconnectAllServices(
}
}
and my PCML file:
<pcml version="3.0">
<program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/
<data name="sysname" type="char" length="10" usage="inputoutput" init="XXXXXXX"/>
</program>
</pcml>
It's the returnvalue that I want to get at, but it isn't passed as a parameter (like sysname is)
??
Can you show your imports?
ASKER
import com.ibm.as400.data.Program CallDocume nt;
import com.ibm.as400.data.PcmlExc eption;
import com.ibm.as400.access.AS400 ;
import com.ibm.as400.access.AS400 Message;
import java.math.BigDecimal;
import com.ibm.as400.data.PcmlExc
import com.ibm.as400.access.AS400
import com.ibm.as400.access.AS400
import java.math.BigDecimal;
I'd need quite a while to get into this very unfamiliar API, but it looks like output data is being obtained here:
http://www-919.ibm.com/servers/eserver/iseries/developer/java/documents/pcml.html. Look at the first Java source file
http://www-919.ibm.com/servers/eserver/iseries/developer/java/documents/pcml.html. Look at the first Java source file
ASKER
Yes, output data is being obtained, but not the returnvalue attribute. Its not used in either of these examples. This is a problem with legacy RPG code which uses a return value to determine if a procedure completed or not. I reckon that new code would avoid using a return value (when it knows its to be accessed from Java with PCML) so its a problem I'll have to work around for now (means not using PCML, so extra coding).
Do you mind if I leave this question open for a few days to see if anyone else comes up with an answer? (I don't think they will - I've crawled the web looking for references to the returnvalue attribute with little success) If nothing turns up, then the points are yours CEHJ.
Cheers,
Steve
Do you mind if I leave this question open for a few days to see if anyone else comes up with an answer? (I don't think they will - I've crawled the web looking for references to the returnvalue attribute with little success) If nothing turns up, then the points are yours CEHJ.
Cheers,
Steve
try this code..
Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">
<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
<!-- Format AUTU0150 - Other formats are available -->
<struct name="autu0150">
<data name="name" type="char" length="10" />
<data name="userOrGroup" type="char" length="1" />
<data name="groupMembers" type="char" length="1" />
<data name="description" type="char" length="50" />
</struct>
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<data name="totalRcds" type="int" length="4" />
<data name="rcdsReturned" type="int" length="4" />
<data name="rqsHandle" type="byte" length="4" />
<data name="rcdLength" type="int" length="4" />
<data name="infoComplete" type="char" length="1" />
<data name="dateCreated" type="char" length="7" />
<data name="timeCreated" type="char" length="6" />
<data name="listStatus" type="char" length="1" />
<data type="byte" length="1" />
<data name="lengthOfInfo" type="int" length="4" />
<data name="firstRecord" type="int" length="4" />
<data type="byte" length="40" />
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
<program name="qgyolaus" path="/QSYS.lib/QGY.lib/QG YOLAUS.pgm " parseorder="listInfo receiver">
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn ed" outputsize="receiverLength " />
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="format" type="char" length="10" usage="input" init="AUTU0150" />
<data name="selection" type="char" length="10" usage="input" init="*USER" />
<data name="member" type="char" length="10" usage="input" init="*NONE" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYGTLE returned additional "records" from the list
created by QGYOLAUS. -->
<program name="qgygtle" path="/QSYS.lib/QGY.lib/QG YGTLE.pgm" parseorder="listInfo receiver">
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn ed" outputsize="receiverLength " />
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="startingRcd" type="int" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
<program name="qgyclst" path="/QSYS.lib/QGY.lib/QG YCLST.pgm" >
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
</pcml>
Java program source for calling QGYOLAUS
import com.ibm.as400.data.Program CallDocume nt;
import com.ibm.as400.data.PcmlExc eption;
import com.ibm.as400.access.AS400 ;
import com.ibm.as400.access.AS400 Message;
// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
public static void main(String[] argv)
{
AS400 as400System; // com.ibm.as400.access.AS400
ProgramCallDocument pcml; // com.ibm.as400.data.Program CallDocume nt
boolean rc = false; // Return code from ProgramCallDocument.callPr ogram()
String msgId, msgText; // Messages returned from AS/400
Object value; // Return value from ProgramCallDocument.getVal ue()
int[] indices = new int[1]; // Indices for access array value
int nbrRcds, // Number of records returned from QGYOLAUS and QGYGTLE
nbrUsers; // Total number of users retrieved
String listStatus; // Status of list on AS/400
byte[] requestHandle = new byte[4];
System.setErr(System.out);
// Construct AS400 without parameters, user will be prompted
as400System = new AS400();
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlM essageLog. setTraceEn abled(true );
System.out.println("Beginn ing PCML Example..");
System.out.println(" Constructing ProgramCallDocument for QGYOLAUS API...");
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qgyolaus.pcml.ser" or
// PCML source file "qgyolaus.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400S ystem, "qgyolaus");
// All input parameters have default values specified in the PCML source.
// Do not need to set them using Java code.
// Request to call the API
// User will be prompted to sign on to the system
System.out.println(" Calling QGYOLAUS API requesting information for the sign-on user.");
rc = pcml.callProgram("qgyolaus ");
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgyol aus");
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYOLAUS failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYOLAUS succeeded
// Write some of the results to standard output
else
{
boolean doneProcessingList = false;
String programName = "qgyolaus";
nbrUsers = 0;
while (!doneProcessingList)
{
nbrRcds = pcml.getIntValue(programNa me + ".listInfo.rcdsReturned");
requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
// Iterate through list of users
for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
{
value = pcml.getValue(programName + ".receiver.name", indices);
System.out.println("User: " + value);
value = pcml.getValue(programName + ".receiver.description", indices);
System.out.println("\t\t" + value);
}
nbrUsers += nbrRcds;
// See if we retrieved all the users.
// If not, subsequent calls to "Get List Entries" (QGYGTLE)
// would need to be made to retrieve the remaining users in the list.
listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
if ( listStatus.equals("2") // List is marked as "Complete"
|| listStatus.equals("3") ) // Or list is marked "Error building"
{
doneProcessingList = true;
}
else
{
programName = "qgygtle";
// Set input parameters for QGYGTLE
pcml.setValue("qgygtle.req uestHandle ", requestHandle);
pcml.setIntValue("qgygtle. startingRc d", nbrUsers + 1);
// Call "Get List Entries" (QGYGTLE) to get more users from list
rc = pcml.callProgram("qgygtle" );
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgygt le");
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYGTLE failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYGTLE succeeded
}
}
System.out.println("Number of users returned: " + nbrUsers);
// Call the "Close List" (QGYCLST) API
pcml.setValue("qgyclst.req uestHandle ", requestHandle);
rc = pcml.callProgram("qgyclst" );
}
}
catch(PcmlException e)
{
System.out.println(e.getLo calizedMes sage());
e.printStackTrace();
System.out.println("*** Call to QGYOLAUS failed. ***");
System.exit(0);
}
System.exit(0);
}
}
Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">
<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
<!-- Format AUTU0150 - Other formats are available -->
<struct name="autu0150">
<data name="name" type="char" length="10" />
<data name="userOrGroup" type="char" length="1" />
<data name="groupMembers" type="char" length="1" />
<data name="description" type="char" length="50" />
</struct>
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<data name="totalRcds" type="int" length="4" />
<data name="rcdsReturned" type="int" length="4" />
<data name="rqsHandle" type="byte" length="4" />
<data name="rcdLength" type="int" length="4" />
<data name="infoComplete" type="char" length="1" />
<data name="dateCreated" type="char" length="7" />
<data name="timeCreated" type="char" length="6" />
<data name="listStatus" type="char" length="1" />
<data type="byte" length="1" />
<data name="lengthOfInfo" type="int" length="4" />
<data name="firstRecord" type="int" length="4" />
<data type="byte" length="40" />
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
<program name="qgyolaus" path="/QSYS.lib/QGY.lib/QG YOLAUS.pgm " parseorder="listInfo receiver">
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn ed" outputsize="receiverLength " />
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="format" type="char" length="10" usage="input" init="AUTU0150" />
<data name="selection" type="char" length="10" usage="input" init="*USER" />
<data name="member" type="char" length="10" usage="input" init="*NONE" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYGTLE returned additional "records" from the list
created by QGYOLAUS. -->
<program name="qgygtle" path="/QSYS.lib/QGY.lib/QG YGTLE.pgm" parseorder="listInfo receiver">
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn ed" outputsize="receiverLength " />
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="startingRcd" type="int" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
<program name="qgyclst" path="/QSYS.lib/QGY.lib/QG YCLST.pgm" >
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
</pcml>
Java program source for calling QGYOLAUS
import com.ibm.as400.data.Program CallDocume nt;
import com.ibm.as400.data.PcmlExc eption;
import com.ibm.as400.access.AS400 ;
import com.ibm.as400.access.AS400 Message;
// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
public static void main(String[] argv)
{
AS400 as400System; // com.ibm.as400.access.AS400
ProgramCallDocument pcml; // com.ibm.as400.data.Program CallDocume nt
boolean rc = false; // Return code from ProgramCallDocument.callPr ogram()
String msgId, msgText; // Messages returned from AS/400
Object value; // Return value from ProgramCallDocument.getVal ue()
int[] indices = new int[1]; // Indices for access array value
int nbrRcds, // Number of records returned from QGYOLAUS and QGYGTLE
nbrUsers; // Total number of users retrieved
String listStatus; // Status of list on AS/400
byte[] requestHandle = new byte[4];
System.setErr(System.out);
// Construct AS400 without parameters, user will be prompted
as400System = new AS400();
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlM essageLog. setTraceEn abled(true );
System.out.println("Beginn ing PCML Example..");
System.out.println(" Constructing ProgramCallDocument for QGYOLAUS API...");
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qgyolaus.pcml.ser" or
// PCML source file "qgyolaus.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400S ystem, "qgyolaus");
// All input parameters have default values specified in the PCML source.
// Do not need to set them using Java code.
// Request to call the API
// User will be prompted to sign on to the system
System.out.println(" Calling QGYOLAUS API requesting information for the sign-on user.");
rc = pcml.callProgram("qgyolaus ");
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgyol aus");
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYOLAUS failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYOLAUS succeeded
// Write some of the results to standard output
else
{
boolean doneProcessingList = false;
String programName = "qgyolaus";
nbrUsers = 0;
while (!doneProcessingList)
{
nbrRcds = pcml.getIntValue(programNa me + ".listInfo.rcdsReturned");
requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
// Iterate through list of users
for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
{
value = pcml.getValue(programName + ".receiver.name", indices);
System.out.println("User: " + value);
value = pcml.getValue(programName + ".receiver.description", indices);
System.out.println("\t\t" + value);
}
nbrUsers += nbrRcds;
// See if we retrieved all the users.
// If not, subsequent calls to "Get List Entries" (QGYGTLE)
// would need to be made to retrieve the remaining users in the list.
listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
if ( listStatus.equals("2") // List is marked as "Complete"
|| listStatus.equals("3") ) // Or list is marked "Error building"
{
doneProcessingList = true;
}
else
{
programName = "qgygtle";
// Set input parameters for QGYGTLE
pcml.setValue("qgygtle.req uestHandle ", requestHandle);
pcml.setIntValue("qgygtle. startingRc d", nbrUsers + 1);
// Call "Get List Entries" (QGYGTLE) to get more users from list
rc = pcml.callProgram("qgygtle" );
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgygt le");
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYGTLE failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYGTLE succeeded
}
}
System.out.println("Number of users returned: " + nbrUsers);
// Call the "Close List" (QGYCLST) API
pcml.setValue("qgyclst.req uestHandle ", requestHandle);
rc = pcml.callProgram("qgyclst" );
}
}
catch(PcmlException e)
{
System.out.println(e.getLo calizedMes sage());
e.printStackTrace();
System.out.println("*** Call to QGYOLAUS failed. ***");
System.exit(0);
}
System.exit(0);
}
}
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/rzahh/page1.htm
best of luck..
R.K
Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">
<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
<!-- Format AUTU0150 - Other formats are available -->
<struct name="autu0150">
<data name="name" type="char" length="10" />
<data name="userOrGroup" type="char" length="1" />
<data name="groupMembers" type="char" length="1" />
<data name="description" type="char" length="50" />
</struct>
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<data name="totalRcds" type="int" length="4" />
<data name="rcdsReturned" type="int" length="4" />
<data name="rqsHandle" type="byte" length="4" />
<data name="rcdLength" type="int" length="4" />
<data name="infoComplete" type="char" length="1" />
<data name="dateCreated" type="char" length="7" />
<data name="timeCreated" type="char" length="6" />
<data name="listStatus" type="char" length="1" />
<data type="byte" length="1" />
<data name="lengthOfInfo" type="int" length="4" />
<data name="firstRecord" type="int" length="4" />
<data type="byte" length="40" />
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
<program name="qgyolaus" path="/QSYS.lib/QGY.lib/QG
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="format" type="char" length="10" usage="input" init="AUTU0150" />
<data name="selection" type="char" length="10" usage="input" init="*USER" />
<data name="member" type="char" length="10" usage="input" init="*NONE" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYGTLE returned additional "records" from the list
created by QGYOLAUS. -->
<program name="qgygtle" path="/QSYS.lib/QGY.lib/QG
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="startingRcd" type="int" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
<program name="qgyclst" path="/QSYS.lib/QGY.lib/QG
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
</pcml>
Java program source for calling QGYOLAUS
import com.ibm.as400.data.Program
import com.ibm.as400.data.PcmlExc
import com.ibm.as400.access.AS400
import com.ibm.as400.access.AS400
// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
public static void main(String[] argv)
{
AS400 as400System; // com.ibm.as400.access.AS400
ProgramCallDocument pcml; // com.ibm.as400.data.Program
boolean rc = false; // Return code from ProgramCallDocument.callPr
String msgId, msgText; // Messages returned from AS/400
Object value; // Return value from ProgramCallDocument.getVal
int[] indices = new int[1]; // Indices for access array value
int nbrRcds, // Number of records returned from QGYOLAUS and QGYGTLE
nbrUsers; // Total number of users retrieved
String listStatus; // Status of list on AS/400
byte[] requestHandle = new byte[4];
System.setErr(System.out);
// Construct AS400 without parameters, user will be prompted
as400System = new AS400();
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlM
System.out.println("Beginn
System.out.println(" Constructing ProgramCallDocument for QGYOLAUS API...");
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qgyolaus.pcml.ser" or
// PCML source file "qgyolaus.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400S
// All input parameters have default values specified in the PCML source.
// Do not need to set them using Java code.
// Request to call the API
// User will be prompted to sign on to the system
System.out.println(" Calling QGYOLAUS API requesting information for the sign-on user.");
rc = pcml.callProgram("qgyolaus
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgyol
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYOLAUS failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYOLAUS succeeded
// Write some of the results to standard output
else
{
boolean doneProcessingList = false;
String programName = "qgyolaus";
nbrUsers = 0;
while (!doneProcessingList)
{
nbrRcds = pcml.getIntValue(programNa
requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
// Iterate through list of users
for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
{
value = pcml.getValue(programName + ".receiver.name", indices);
System.out.println("User: " + value);
value = pcml.getValue(programName + ".receiver.description", indices);
System.out.println("\t\t" + value);
}
nbrUsers += nbrRcds;
// See if we retrieved all the users.
// If not, subsequent calls to "Get List Entries" (QGYGTLE)
// would need to be made to retrieve the remaining users in the list.
listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
if ( listStatus.equals("2") // List is marked as "Complete"
|| listStatus.equals("3") ) // Or list is marked "Error building"
{
doneProcessingList = true;
}
else
{
programName = "qgygtle";
// Set input parameters for QGYGTLE
pcml.setValue("qgygtle.req
pcml.setIntValue("qgygtle.
// Call "Get List Entries" (QGYGTLE) to get more users from list
rc = pcml.callProgram("qgygtle"
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgygt
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYGTLE failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYGTLE succeeded
}
}
System.out.println("Number
// Call the "Close List" (QGYCLST) API
pcml.setValue("qgyclst.req
rc = pcml.callProgram("qgyclst"
}
}
catch(PcmlException e)
{
System.out.println(e.getLo
e.printStackTrace();
System.out.println("*** Call to QGYOLAUS failed. ***");
System.exit(0);
}
System.exit(0);
}
}
Example of retrieving a list of information
PCML source for calling QGYOLAUS
<pcml version="1.0">
<!-- PCML source for calling "Open List of Authorized Users" (QGYOLAUS) API -->
<!-- Format AUTU0150 - Other formats are available -->
<struct name="autu0150">
<data name="name" type="char" length="10" />
<data name="userOrGroup" type="char" length="1" />
<data name="groupMembers" type="char" length="1" />
<data name="description" type="char" length="50" />
</struct>
<!-- List information structure (common for "Open List" type APIs) -->
<struct name="listInfo">
<data name="totalRcds" type="int" length="4" />
<data name="rcdsReturned" type="int" length="4" />
<data name="rqsHandle" type="byte" length="4" />
<data name="rcdLength" type="int" length="4" />
<data name="infoComplete" type="char" length="1" />
<data name="dateCreated" type="char" length="7" />
<data name="timeCreated" type="char" length="6" />
<data name="listStatus" type="char" length="1" />
<data type="byte" length="1" />
<data name="lengthOfInfo" type="int" length="4" />
<data name="firstRecord" type="int" length="4" />
<data type="byte" length="40" />
</struct>
<!-- Program QGYOLAUS and its parameter list for retrieving AUTU0150 format -->
<program name="qgyolaus" path="/QSYS.lib/QGY.lib/QG
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="format" type="char" length="10" usage="input" init="AUTU0150" />
<data name="selection" type="char" length="10" usage="input" init="*USER" />
<data name="member" type="char" length="10" usage="input" init="*NONE" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYGTLE returned additional "records" from the list
created by QGYOLAUS. -->
<program name="qgygtle" path="/QSYS.lib/QGY.lib/QG
<data name="receiver" type="struct" struct="autu0150" usage="output"
count="listInfo.rcdsReturn
<data name="receiverLength" type="int" length="4" usage="input" init="16384" />
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="listInfo" type="struct" struct="listInfo" usage="output" />
<data name="rcdsToReturn" type="int" length="4" usage="input" init="264" />
<data name="startingRcd" type="int" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
<!-- Program QGYCLST closes the list, freeing resources on the AS/400 -->
<program name="qgyclst" path="/QSYS.lib/QGY.lib/QG
<data name="requestHandle" type="byte" length="4" usage="input" />
<data name="errorCode" type="int" length="4" usage="input" init="0" />
</program>
</pcml>
Java program source for calling QGYOLAUS
import com.ibm.as400.data.Program
import com.ibm.as400.data.PcmlExc
import com.ibm.as400.access.AS400
import com.ibm.as400.access.AS400
// Example program to call "Retrieve List of Authorized Users" (QGYOLAUS) API
public class qgyolaus
{
public static void main(String[] argv)
{
AS400 as400System; // com.ibm.as400.access.AS400
ProgramCallDocument pcml; // com.ibm.as400.data.Program
boolean rc = false; // Return code from ProgramCallDocument.callPr
String msgId, msgText; // Messages returned from AS/400
Object value; // Return value from ProgramCallDocument.getVal
int[] indices = new int[1]; // Indices for access array value
int nbrRcds, // Number of records returned from QGYOLAUS and QGYGTLE
nbrUsers; // Total number of users retrieved
String listStatus; // Status of list on AS/400
byte[] requestHandle = new byte[4];
System.setErr(System.out);
// Construct AS400 without parameters, user will be prompted
as400System = new AS400();
try
{
// Uncomment the following to get debugging information
//com.ibm.as400.data.PcmlM
System.out.println("Beginn
System.out.println(" Constructing ProgramCallDocument for QGYOLAUS API...");
// Construct ProgramCallDocument
// First parameter is system to connect to
// Second parameter is pcml resource name. In this example,
// serialized PCML file "qgyolaus.pcml.ser" or
// PCML source file "qgyolaus.pcml" must be found in the classpath.
pcml = new ProgramCallDocument(as400S
// All input parameters have default values specified in the PCML source.
// Do not need to set them using Java code.
// Request to call the API
// User will be prompted to sign on to the system
System.out.println(" Calling QGYOLAUS API requesting information for the sign-on user.");
rc = pcml.callProgram("qgyolaus
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgyol
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYOLAUS failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYOLAUS succeeded
// Write some of the results to standard output
else
{
boolean doneProcessingList = false;
String programName = "qgyolaus";
nbrUsers = 0;
while (!doneProcessingList)
{
nbrRcds = pcml.getIntValue(programNa
requestHandle = (byte[]) pcml.getValue(programName + ".listInfo.rqsHandle");
// Iterate through list of users
for (indices[0] = 0; indices[0] < nbrRcds; indices[0]++)
{
value = pcml.getValue(programName + ".receiver.name", indices);
System.out.println("User: " + value);
value = pcml.getValue(programName + ".receiver.description", indices);
System.out.println("\t\t" + value);
}
nbrUsers += nbrRcds;
// See if we retrieved all the users.
// If not, subsequent calls to "Get List Entries" (QGYGTLE)
// would need to be made to retrieve the remaining users in the list.
listStatus = (String) pcml.getValue(programName + ".listInfo.listStatus");
if ( listStatus.equals("2") // List is marked as "Complete"
|| listStatus.equals("3") ) // Or list is marked "Error building"
{
doneProcessingList = true;
}
else
{
programName = "qgygtle";
// Set input parameters for QGYGTLE
pcml.setValue("qgygtle.req
pcml.setIntValue("qgygtle.
// Call "Get List Entries" (QGYGTLE) to get more users from list
rc = pcml.callProgram("qgygtle"
// If return code is false, we received messages from the AS/400
if(rc == false)
{
// Retrieve list of AS/400 messages
AS400Message[] msgs = pcml.getMessageList("qgygt
// Iterate through messages and write them to standard output
for (int m = 0; m < msgs.length; m++)
{
msgId = msgs[m].getID();
msgText = msgs[m].getText();
System.out.println(" " + msgId + " - " + msgText);
}
System.out.println("** Call to QGYGTLE failed. See messages above **");
System.exit(0);
}
// Return code was true, call to QGYGTLE succeeded
}
}
System.out.println("Number
// Call the "Close List" (QGYCLST) API
pcml.setValue("qgyclst.req
rc = pcml.callProgram("qgyclst"
}
}
catch(PcmlException e)
{
System.out.println(e.getLo
e.printStackTrace();
System.out.println("*** Call to QGYOLAUS failed. ***");
System.exit(0);
}
System.exit(0);
}
}
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/rzahh/page1.htm
best of luck..
R.K
ASKER
I would, but it doesn't address my problem.
Let me clarify - I can get the PCML and Java working, in order to pass and retrieve parameters - that isn't the problem.
The problem is with the returnvalue attribute in the program element:
<program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/ SRV_SYSNM2 .srvpgm" returnvalue="integer">
i.e. returnvalue="integer"
This is the value I'd like to get hold of. Unfortunately it doesn't appear to be available (as its never assigned a name).
I know that its being passed back though, because I get an AS400 error if its not in the form of a PackedDecimal (in RPG) AND if I've specified it within the PCML file.
Steve.
Let me clarify - I can get the PCML and Java working, in order to pass and retrieve parameters - that isn't the problem.
The problem is with the returnvalue attribute in the program element:
<program name="GETSYSNAMJ" entrypoint="GETSYSNAMJ" path="/QSYS.lib/XHAJN.lib/
i.e. returnvalue="integer"
This is the value I'd like to get hold of. Unfortunately it doesn't appear to be available (as its never assigned a name).
I know that its being passed back though, because I get an AS400 error if its not in the form of a PackedDecimal (in RPG) AND if I've specified it within the PCML file.
Steve.
>>Do you mind if I leave this question open for a few days ...
No of course not. What i'd look for is the abstraction in the api that encapsulates the actual machine process. You should be able to get the process return value from this.
No of course not. What i'd look for is the abstraction in the api that encapsulates the actual machine process. You should be able to get the process return value from this.
ASKER
Well, I found the solution!!!
The ProgramCallDocument class (which is the class used to call the PCML-specified program) has a method named getIntReturnValue(String name), and the name to be specified as a parameter is the name of the program element in the PCML document (in my case GETSYSNAMJ).
So adding the method:
int x = pcml.getIntReturnValue("GE TSYSNAMJ") ;
copies the returnvalue into x.
Phew.
Thanks all for your help.
Cheers,
Steve
The ProgramCallDocument class (which is the class used to call the PCML-specified program) has a method named getIntReturnValue(String name), and the name to be specified as a parameter is the name of the program element in the PCML document (in my case GETSYSNAMJ).
So adding the method:
int x = pcml.getIntReturnValue("GE
copies the returnvalue into x.
Phew.
Thanks all for your help.
Cheers,
Steve
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.