How do I debug a Program Call problem?
The Toolbox's Program Call component carries out its task by calling the Remote Command host server on IBM i, which is part of i5/OS option 12. This server is used by both the Toolbox and Client Access/400 to call programs on the server.
The Toolbox communicates with the server via sockets/TCP. When the Java program and the Toolbox zip/jar files are on a client, normal sockets/TCP is used to get to the server. When the Java program, the Toolbox zip/jar file and the RPG program are all on the same server, local sockets are used to call this server. This is faster than 'normal' sockets but the key point is we will do a call to the server even when everything is on the same server.
When the host servers are started, jobs are created to catch our program call requests. As you have noticed, these jobs start under profile QUSER.
When we call the host server, we supply a userid and password. The host server swaps to the profile we supply, runs the specified program, then swaps back to QUSER so it is ready to carry out the next request. The program is not run under the QUSER profile, it is run under an actual user profile. The Toolbox gets the userid/password in one of three ways:
- The Java program can programatically set the userid/password via methods on the AS400 object.
- If on a client, the Toolbox will prompt for userid/password.
- If on the i5/OS JVM, the Toolbox will use the userid/password of the i5/OS job the Java program is running in.
Since the server swaps to a profile other than QUSER before running the program, the library list of the user profile is in effect.
Debugging this process can be a challenge. The server puts the profile it swapped to (and additional debug information) in the job log, but finding that job log can be difficult. It is hard because the real profile does not show up on the WRKACTJOB screen. The jobs on that screen are always listed as belonging to QUSER.
Here are some debugging hints our server team has put together:
- Identifying which server job that your request will go to:
Ensuring that there is only one prestart job is one way to help ensure that you know which prestart job will handle the request from the client.
- Do a WRKACTJOB and press F14 to see all the prestart jobs.
- Page down until you find the subsystem for the server that you want to work with.
- Once you have that type a 4 in the Option field for all but one of the server jobs that are in PSRW status.
- Refresh the screen and type a 5 in the option field for the remaining PSRW status server.
- This should be the job that will be used on the next new connection and request.
- Issue the STRSRVJOB for this job and trace or start debug.
Holding QBATCH is another way to make sure of the job number that you will get for a specific server request.
The server daemon job (the one that controls the pre-started jobs) is QZRCSRVSD. The server job is QZRCSRVS.
- Saving job logs:
i5/OS jobs have a log. Most i5/OS programs write status and error messages to the job log as they run. Our Program Call server is no different. As it runs it dumps information to the job log as it runs. When most jobs end, the job log goes to an output queue. Our servers are different here. They start and stop so often during normal processing, that writing their job log to an output queue would eventually take all the space on the server. To avoid this problem the server does not write its job log to an output queue. It throws it away. The problem is that, in a debugging situation, there is valuable data in the job log.
When debugging you want the job log saved so that you can figure out what is wrong with the programs. You can override the default 'discard-job-log' behavior by changing the job description of the server job. The job description has a whole pile of run-time tuning knobs for the server jobs. Changing one of these parameters tells the server job to save the job log.
Using the CHGJOBD command, specify the appropriate Job Description (QDFTJOBD or QZBSJOBD), and set the "Message logging" parameter's "Text" option to *SECLVL
- On pre-V4R4 systems, the name of the Client Access Host Server Job Description object is QDFTJOBD.
- In V4R4, the object is named QZBSJOBD.
- Service program entry point names:
When calling a service program, the entry point name is case sensitive. If the run() method fails with i5/OS message
"CPF226E - Value for a parameter was not valid" , there is a good chance that the case of the entry point name is incorrect.