STAF FAQ

October 7, 2003


CONTENTS

1. INTRODUCTION
2. SETUP
3. DEBUGGING
4. GLOBALIZATION


1. INTRODUCTION

1.1 What is STAF?
1.2 What operating systems are supported by STAF?
1.3 Where can I get STAF?
1.4 Is STAF Open Source?
1.5 What documentation exists for STAF?
1.6 How can I get on/off STAF mailing lists?
1.7 How can I get help?
1.8 How can I request a feature for STAF?
1.9 Why isn't STAF written in Java?
1.10 What is the performance overhead of running STAF?

2. SETUP

2.1 How do I install STAF?
2.2 How do I install STAF in silent mode?
2.3 How do I configure STAF?
2.4 How do I interact with STAF?
2.5 How can I redirect output from a process started by STAF?
2.6 How can I run a complex command that I can type at a shell (command) prompt via STAF?
2.7 How do you make each application have its own STAF log file?
2.8 AIX STAF environment variables (PATH, LIBPATH, etc.) are not set when opening a terminal
2.9 How to have STAF start automatically during reboot on Unix platforms
2.10 The InstallShield installer fails, or does not complete the installation, on certain versions of Linux
2.11 27:Error starting JVM using JVMName: STAFJVM1, JVM: java, JVMOptions:  , RC: 10,  OSRC: 2
2.12 Starting STAF as a Windows service
2.13 STAF fails to init with Windows Terminal Server
2.14 STAF ISMP install fails - how do I get debug information?

3. DEBUGGING

3.1 What to do if you are having a problem with STAF or one of its services
3.2 Information to include when asking questions or reporting bugs
3.3 When attempting to run a process, it fails with a RC 10
3.4 When attempting to send a STAF request to a remote machine, it fails with a RC 16
3.5 When attempting to start STAF, it fails with "Error binding server socket, rc = 67"
3.6 When attempting to start STAF, it fails with "Error binding server socket, rc = 10048"
3.7 When attempting to start a process on  a remote machine, it fails with a RC 25
3.8 When the STAF InstallShield MultiPlatform installer is executed, it generates a series of dots, but the installer never completes
3.9 Interacting with queues for processes started via the command line
3.10 STAF machines can't communicate
3.11 STAX still shows a process as running, even though it has completed
3.12 RC 2 when starting the STAX Job Monitor
3.13 RC 16 when starting the STAX Job Monitor
3.14 RC 2 when submitting new jobs through the STAX Job Monitor
3.15 RC 16 when submitting new jobs through the STAX Job Monitor
3.16 Process started successfully by STAF, but the process can't log its output to an AFS directory
3.17 STAF startup fails with 38:Illegal access to class: com.ibm.staf.service....
3.18 Text files not converted correctly between Windows and Unix
3.19 How to have multiple programs use a static handle to access variables and log data
3.20 If I edit a STAF log, it appears to be in some weird format
3.21 STAF's user registration fails each time STAF is started
3.22 When running STAFInst on Solaris, it fails with "test: unknown operator -ef"
3.23 Running "java -jar STAXMon.jar" results in java.util.zip.ZipException
3.24 FS service COPY FILE fails when no TOMACHINE is specified
3.25 Can't get Help on errors when STAF is not running
3.26 STAX Job Monitor window doesn't have a close confirmation
3.27 Why are there are more STAF processes on Linux?
3.28 The Echo, Ping, and Delay services do not provide help
3.29 HP-UX SIGABRT after a STAF process has completed
3.30 Error initializing service, RESPOOL, RC: 4008
3.31 Unix error message: "STAFProcessManager::processMonitorThread: Parent could not set child's pgid: 13"
3.32 Email service SEND request results in RC 7 when quotes or double quotes are in the message
3.33 Child processes are not killed on Windows
3.34 "JAR Archive failed security check corrupt JAR file" message after downloading a STAF jar file
3.35 RC=10 and STAFResult=8 when starting a Java process in a STAX job
3.36 Changes to imported Python module not picked up in STAX job
3.37 Does the HTTP Service retain session information across multiple requests?
3.38 Unix error message: STAFProcessManager::processMonitorThread: Could not start process (execve): 8
3.39 Problems accessing a Java service, such as RC=6
3.40 On some Unix platforms (such as Solaris), exiting the STAFProc terminal causes STAF to terminate
3.41 How do you access system date and time in STAX?
3.42 Are there any conflict or efficiency concerns with using STAX <import> when doing nested file imports?
3.43 Can you use the <stopusing> element in a STAX job that runs on both Windows and Unix?
3.44 How do I find out more information about Python?
3.45 In recent versions of STAF, I no longer see any Java service output in the STAFProc console
3.46 When importing a STAX function from another XML file, are the global <script>s in the XML file executed?
3.47 Are STAF system variable values available in STAX?
3.48 How do you search for multiple strings in testcase output files in STAX?
3.49 Can you use STAF and STAX with VMWare images?
3.50 Does a STAX process element use the workdir element as the path to the command?">
3.51 Why am I getting a java.lang.NullPointerException at org.python.core.ThreadState.entrRepr in my JVMLog.1 file?


3. GLOBALIZATION

4.1 How do I use STAF/STAX in environments where machines running STAF have different locales?
4.2 How do I specify non-ASCII characters in a STAF request or STAX job?
4.3 How do I know what codepage STAF is using on my machine?


1. INTRODUCTION


1.1 What is STAF?

STAF stands for "Software Testing Automation Framework. As its name indicates, STAF is an automation framework. It is intended to make it easier to create and manage automated testcases and test environments.

STAF externalizes its capabilities through services. A service provides a focused set of functionality, such as, Logging, Process Invocation, etc. STAFProc is the process that runs on a machine, called a STAF Client, which accepts requests and routes them to the appropriate service. These requests may come from the local machine or from another STAF Client. Thus, STAF works in a peer environment, where machines may make requests of services on other machines.

STAF was designed with the following points in mind.


1.2 What operating systems are supported by STAF?

STAF 2.4 is supported on the following operating systems:

If you need support for another operating system, open a feature request on the STAF SourceForge web site.

If you can't wait, port STAF to your favorite operating system yourself since STAF is open sourced.


1.3 Where can I get STAF?

STAF software, information, documentation, etc. can be found at the STAF SourceForge web site.


1.4 Is STAF Open Source?

Yes! STAF is released under the GNU LGPL.


1.5 What documentation exists for STAF?

The following documents can be found at the STAF SourceForge web site.


1.6 How can I get on/off STAF mailing lists?

Go to the STAF Mailing Lists web page and click on Subscribe or Unsubscribe for the STAF mailing list that you want to be added to or removed from.


1.7 How can I get help?

You can submit questions using the STAF Mailing Lists and the STAF Discussion Forums on SourceForge.

If you are an IBMer, you may use IBM Internal Newsgroups to submit questions for STAF. The following news groups (on-line discussons) exist for STAF:

You can also get help about a STAF service's request syntax by using the following command:

    staf local <service> help

This will return the available options for the <service>.

You can find out more information about STAF error codes by using the following command:

    staf local help error 7

This will return detailed information about error code 7.


1.8 How can I request a feature for STAF?

To request a feature (or browse a list of requested features), click here.


1.9 Why isn't STAF written in Java?

1) STAF was designed to put as few dependencies on the underlying system as possible.  To that end we designed STAF to consume as little memory, disk, and CPU as possible.  Some of these items (particularly disk space) aren't nearly as important as they were several years ago.  However, almost every new group that picks up STAF asks this very same question, "How much <room> does STAF require?".  Along these same lines, we didn't want to require any additional software on the system in order to run STAF.  Writing STAF in Java would obviously require a JVM.  Of the three resources previously listed, this has the largest impact on memory, and then CPU.  Again, this isn't as large an issue as it once was, as many/most systems today have a JVM.  Nevertheless, we have many groups who are reluctant to put a JVM on their system, particularly those doing base OS testing (like the AIX and Linux Technology Center) teams, and they definitely don't like being dependent on a JVM.  For example, we have a group using STAF on Linux/PPC-64.  This platform still doesn't have a stable JVM.  And, the Linux JVMs, in general, have struggled for stability of the years (particularly on SMP systems).  For what it's worth, we've had people tell us that STAF should have been built using MQ Series, or Java, or Perl, or <insert favorite technology>.  Obviously, we can't appease all these groups, as they are mutually exclusive requests.  In the end, STAF only depends on a base operating system, and a working compiler (for use in porting it).

The following items all deal with the inability to write a 100% pure-Java implementation.  If you can't go 100% (or darn close to it), a lot of Java's appeal dies away.

2) STAF is designed to be extensible from a variety of languages.  In order to invoke these other languages, you need the ability to call native code.  Obviously, from Java, this puts you into JNI land and out of 100% pure-Java land.  At the moment, STAF supports service written in C/C++, Java, and Rexx.  Perl support is being actively developed in Hursley.  Other languages are feasible, given a way to communicate with the language from C/C++.  For example, we have prototyped Tcl and Python service support, but have not done full-blown implementations due to lack of user demand, although both languages are picking up steam (from their user communities).  For what its worth, C/C++ and Java are the most common implementation languages for STAF services.  Rexx was important early in STAF's life, but has effectively died off (from a service point of view), although there are a few groups that still use it do to Rexx having a long heritage (and deep roots) at IBM.

3) Performance.  Several of STAF's services (due to their nature) require as much performance as they can squeeze out (Log and Monitor are the primary examples here).  This, effectively, means writing them in C/C++.  In addition, the (local) IPC  performance is important for the performance of STAF.  To get the best performance here, you need to use native IPC communications instead of IP Sockets (when talking locally).  Some OSes (notably AIX, at least when we tested on the 4.3 release a couple of years ago), have horrible performance for local IP Sockets when compared with their native IPC mechanisms (e.g., Unix sockets, named/anonymous pipes, shared memory).  Again, from a Java perspective, these things put you  in JNI land.  And, then, of course, there is your basic run-of-the-mill performance problems with Java.  The JIT helps, but rarely comes anywhere near natively compiled code.

4) Access to base OS features.  The most important example here is starting processes (e.g., STAF's Process service).  We allow you to specify alternate shells to use when starting processes, to start processes under different user IDs, to specify additional environment variables for the process, amongst other abilities.  Java makes some of these things more difficult to implement (e.g., additional environment variables) and some nigh-impossible (e.g. different user IDs) without resorting to native code.  And, yes, all these items are used by multiple STAF users/teams.  Other items in this category are interacting with security systems and dealing with additional file system attributes (e.g., permission bits on unix systems, attributes on Win32 systems, ACLs on any system), both of which are planned for future versions of STAF.


1.10 What is the performance overhead of running STAF?

As a general rule, STAF takes up very little system resources.  A typical STAF installation is about 10-30 MB (depending on whether you use the installer with the integrated JVM).  STAF's in-memory size (without any additional external services) is about 2.5-5 MB (depending on the platform).  On an idle STAF system (i.e., one in which there are no requests currently being handled by STAF) STAF consumes 0% CPU on a Windows system and a VERY limited amount on unix systems.  On unix, we have a thread which wakes up once a second to see if any STAF processes have completed.  STAF was designed to consume as little system resources as possible, as we know that people want their test systems as close to clean-room conditions as possible.


2. SETUP


2.1 How do I install STAF?

STAF provides its own installation program which uses InstallShield Multi-Platform for supported platforms. On Unix platforms, we also provide a shell script-based installation mechanism.  See the Installation section in the STAF User's Guide for detailed instructions on how to install STAF.  You can find which platforms are supported on InstallShield Multi-Platform at:  http://www.installshield.com/imp/info/specifications.asp


2.2 How do I install STAF in silent mode?

Here are the commands to install STAF in silent mode (these examples are for Win32):

If using the InstallShield MultiPlatform executable:

    STAF250-setup-win32 -silent

If using the InstallShield MultiPlatform Jar file:

    java -jar STAF250-setup-win32.jar -silent

To override the default location where STAF is installed during a silent installation, you can specify the following option (note that this option is only supported on STAF 2.5.0 or higher):

    STAF250-setup-win32 -silent -W stafinstalldirectory.defaultInstallLocation="C:\tools\staf"


2.3 How do I configure STAF?

STAF is configured through a text file called the STAF Configuration File. This file may have any name you desire, but the default is STAF.cfg. The STAF configuration File is read and processed line by line. The various configuration options are described in the Configuration section in the STAF User's Guide.


2.3 How do I interact with STAF?

You can interact with STAF from many languages (Java, C, C++, Rexx, Perl, Tcl) and from the command line/shell prompt. See the "API Reference" and "Commands" sections in the STAF User's Guide for more information.

If you need support for another language, open a feature request on the STAF SourceForge web site.

If you can't wait, provide support for your favorite language yourself since STAF is open sourced.


2.5 How can I redirect output from a process started by STAF?

You can't use the command line redirection symbols, such as '>', with STAF. They won't work. However, STAF's PROCESS service provides several redirection options, namely STDIN, STDOUT, STDOUTAPPEND, STDERR, and STDERRAPPEND, depending on what (and how) you want to redirect.

For example, to start shell script tc3.sh and redirect its standard output to /tmp/tc3.out:

STAF local PRCOESS START COMMAND tc3.sh STDOUT /tmp/tc3.out


2.6 How can I run a complex command that I can type at a shell (command) prompt via STAF?

The PROCESS service has a SHELL parameter which specifies that COMMAND should be executed as though you were at a shell prompt. This allows complex commands involving pipelines to be readily executed. Note, if COMMAND and PARMS are both specified they will be concatenated with a space between them, and the resulting string is what will be executed.

            STAF local PROCESS START SHELL COMMAND "ps | grep test | wc >testcount.txt"             STAF local PROCESS START SHELL COMMAND "dir *.*"

2.7 How do you make each application have its own STAF log file?

Use HANDLE logs instead of GLOBAL logs. With HANDLE logs each application will get a physically separate log file. HANDLE logs keep separate logs for each process even if the processes are using the same log names. The downside to HANDLE logs is you need to remember the handles you were using, so that you can query them. For example if you log data to a handle log, like so

STAF local log LOG HANDLE LOGNAME testit LEVEL info MESSAGE hello

then you can query it like so

STAF local log QUERY MACHINE <x> HANDLE <y> LOGNAME testit

In this request you need to know <x> (which should be your machines name) and <y> which you won't know until your program is executed.

To facilitate HANDLE based logs, it is probably a good idea for programs using them to write their name and handle to a GLOBAL log so that you can determine which HANDLE logs you need to query.


2.8 AIX STAF environment variables (PATH, LIBPATH, etc.) are not set when opening a terminal

Edit the file ~/.Xdefaults (create it in your home directory if it does not exist) and add the following line:

*loginShell:true

Save the changes and logout/login.  Any terminals that you open will have /etc/profile executed automatically (so that STAF's InstallShield environment variable updates will be read).


2.9 How to have STAF start automatically during reboot on Unix platforms

Each Unix platform has a different method to start executables automatically during reboot.

On Linux platforms, add the following lines to the /etc/rc.d/rc.local (or, if on SuSe, /etc/init.d/boot.local) file (substituting your specific locations where STAF and Java are installed):

PATH=/usr/local/staf/bin:/jdk1.3.1/bin:$PATH; export PATH
CLASSPATH=/usr/local/staf/lib/JSTAF.jar:$CLASSPATH; export CLASSPATH
STAFCONVDIR=/usr/local/staf/codepage; export STAFCONVDIR
LD_LIBRARY_PATH=/usr/local/staf/lib:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
/usr/local/staf/bin/STAFProc &

You may get the following error message:

STAFProcess::processMonitorThread: error opening /dev/tty, errno: 6

But STAFProc does start despite this message, and accepts requests.


2.10 The InstallShield installer fails, or does not complete the installation, on certain versions of Linux

InstallShield Multiplatform only supports a subset of Linux versions.  You can view which Linux versions are supported at:  http://www.installshield.com/imp/info/specifications.asp   You may be able to install STAF via InstallShield on non-supported Linux platforms, but errors may be reported during the installation, and you will likely need to set the required environment variables manually:

export PATH=/usr/local/staf/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/staf/lib:$LD_LIBRARY_PATH
export CLASSPATH=/usr/local/staf/lib/JSTAF.jar:$CLASSPATH

If the Linux InstallShield Multiplatform STAF installation fails on Linux, you can use the STAF tar.gz installation file as an alternative.  Please refer to the STAF User's Guide for more information on using the tar.gz installation file.


2.11 27:Error starting JVM using JVMName: STAFJVM1, JVM: java, JVMOptions:  , RC: 10,  OSRC: 2

This error can occur when starting STAFProc if Java STAF services (such as STAX, Event, EventManager, Cron, Email, etc.) are configured in the STAF.cfg file.  In order to run Java STAF services, you must have a version of Java (1.3.0 or later) installed on the machine.  This error message will be displayed if STAFProc can't find the "java" binary executable.  The error message indicates a STAF return code of 10 (which indicates a base OS error), and the OS error code is 2 (which means that the file that the OS attempted to execute could not be found).  In this case, the JVM: indicates that "java" was the file that could not be found.  The "java" binary executable must either be in the PATH environment variable (so that if you type "java -version" from a shell prompt, the executable is found and returns the version number), or you can optionally specify the java executable in the STAF.cfg file, such as:

SERVICE STAX LIBRARY JSTAF EXECUTE C:/STAF/service/STAX.jar OPTION JVM=/opt/sunjdk1.4.0/jre/bin/java


2.12 Starting STAF as a Windows service

Problem:
All supported Windows platforms, when the machine fails and/or is rebooted the STAF process is unavailable for remote commands until a user logs in and starts it.

Solution:
Configure the STAF process as a Windows service that will run automatically when the machine boots.

Environment:
Newly installed Windows 2000 with SP 3, terminal services and latest Microsoft patches. STAF 2.4.4.
Copies of INSTSRV.EXE and SVRANY.EXE (Windows Resource Kit) copied into C:\WINNT\SYSTEM32.
Users connecting through Remote Desktop Client.

Create a base STAF service which by default is started automatically when the system boots.
instsrv STAF c:\winnt\system32\srvany.exe

Use regedit (WARNING: Using Registry Editor incorrectly can cause serious problems that may require you to reinstall your operating system. You cannot guarantee that problems resulting from the incorrect use of Registry Editor can be solved. Use Registry Editor at your own risk.) and find:
My Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\STAF

Create a new string value with the name Description. Set the value to Automatically start STAF service.
Create a new Key with name Parameters. Inside the new key, create a new string value with the name Application. Set the value to c:\staf\bin\stafproc.exe.

Windows 2000 Terminal Server:
Start > Programs > Administrative Tools > Management Console (Windows 2000 Terminal Server)
Services and Applications > Services

or Windows XP Professional
Start > Settings > Control Panel > Administrative Tools
Services

Locate STAF, right click, properties.
From the 'Log On' tab and click 'Allow service to interact with desktop'.
Apply. OK.

Finally
net start staf

Check it is all working from a command prompt.
staf local service list

New problem:
If a user logs on before the STAF process (STAFproc) has initialized, it is possible that they still receive the error 'Error registering with STAF, RC: 21' even after the service has started.

Solution:
Stop and restart the service with due care as others might already be using it.
net stop staf
net start staf

New problem:
STAF should not be started or shutdown with the commands on the start menu when STAF is configured as a service.

Solution:
The service can be restarted by suitably authorized user from the command line with
net stop staf
net start staf
The service can be restarted from the services panel of the management console by right clicking and selecting stop and then right clicking and selecting start.

New problem:
STAF is still started (and fails) when the user who installed it logs in.
Delete STAF from Start > Programs > Startup folder


2.13 STAF fails to init with Windows Terminal Server

Problem:
When using Windows 2000 Terminal Server and Windows XP remote desktop feature with multiple users on a machine, only the user starting the STAF process (STAFproc) can execute STAF commands from the command line. Others users on the machine receive 'Error registering with STAF, RC: 21' when issuing STAF commands.

Solution:
See FAQ topic 2.12 "Starting STAF as a Windows Service".


2.14 STAF ISMP install fails - how do I get debug information?

To generate the STAF ISMP log file, run the ISMP installer with the -is:log option:

STAF-250-setup-linux -is:log /tmp/log.txt

The /tmp/log.txt file (you can name this anything you want) will have details on the installation.


3. DEBUGGING


3.1 What to do if you are having a problem with STAF or one of its services

If you are having a problem with STAF or one of its services, follow these steps to resolve the problem:

  1. View the topics listed below to determine if any of the topics can help you to resolve the problem
  2. View the open Bugs to see if the problem has already been reported
  3. If you are not sure if the problem is a STAF bug, then post a question to the Help forum.

  4. If you are fairly certain that this is a bug with STAF or one of its services, then open a new Bug.

3.2 Information to include when asking questions or reporting bugs

When you are posting to the Help forum or opening a new Bug, the STAF development team will be better able to quickly resolve your problem if you supply the following information:


3.3 When attempting to run a process, it fails with a RC 10

Return code 10 means "Base OS Error", and the additional info provided in STAFResult is the actual error returned by the operating system. One of the most common reasons for getting a Base OS Error is "File Not Found". On Windows systems, OS error code 2 means "The system cannot find the file specified". On Unix systems, OS error code 2 means "No such file or directory".

If you receive an OS error code 2, make sure the the executable or script file is in the PATH of the machine where it will be executed., or fully qualify the COMMAND option on the process request (i.e. /opt/tests/mytest).

For Windows systems, you can find more information for OS error codes by typing "net helpmsg <error code>" (or by typing net help <error code>" on Windows 95/98/ME). So, to find more information for OS error code 2 on a Windows 2000 system, type

net helpmsg 2

For Unix systems, you can find more information for OS error codes from include files named errno.h found in directory /usr/include and its subdirectories.


3.4 When attempting to send a STAF request to a remote machine, it fails with a RC 16

Return code of 16 means "No Path To Machine". This means that STAF could not talk to the target system, with likely causes being:


3.5 When attempting to start STAF, it fails with "Error binding server socket, rc = 67"

This error can occur on Unix if STAFProc has not been shutdown correctly.  The error will be displayed when you attempt to restart STAFProc.

To resolve the problem:

  1. Go to the /tmp directory, and delete STAFIPC_STAFProc and STAFProc.tmp
  2. Type "ps" or "ps -ea" and determine if there are any processes that STAF started which are still running.  If there are any, type "kill xxx" where xxx is the PID for the process.
  3. Restart STAFProc
As a last resort, reboot the machine.


3.6 When attempting to start STAF, it fails with "Error binding server socket, rc = 10048"

This indicates that the socket address is already in use.  This error occurs if STAF attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that wasn't closed properly, or one that is still in the process of closing.

You should wait approximately 2-3 minutes for TCP/IP to complete the socket close and retry starting STAF.  You can also try typing "ps" or "ps -ea" and determine if there are any processes that STAF started which are still running.  If there are any, type "kill xxx" where xxx is the PID for the process.

Note:  Some Solaris systems require a system reboot to fix this condition.


3.7 When attempting to start a process on  a remote machine, it fails with a RC 25

This error indicates that you have submitted a request from a machine which is not authorized to perform the request.  To start a process on a remote machine, a TRUST level of 5 is required.

To resolve the problem:


3.8 When the STAF InstallShield MultiPlatform installer is executed, it generates a series of dots, but the installer never completes

This error can occur on Unix machines when you are telnet'ing into the machine remotely.  The STAF InstallShield MultiPlatform installer is a GUI application, therefore, you must export your DISPLAY from the Unix machine to the machine from which you are telnet'ing.

Most applications will give you an error message if the DISPLAY is not correctly exported, but, there is a bug in InstallShield MultiPlatform where it does not give you an error message and will just sit there.

The solution is to Export your DISPLAY, for example:

export DISPLAY=myHostname.austin.ibm.com:0.0


3.9 Interacting with process queues for processes started via the command line

When you submit a request to STAF from the command line, a unique handle is generated for that request.  After the request completes, that handle is no longer active in STAFProc.  If you were to submit a subsequent STAF request from the command line which referenced that handle or was dependent upon the continued existence of that handle, your request would fail.

Messages are sent to queues associated with specific handles.  So, if you register with STAF, and then someone queues you a message, you can retrieve it off your handle's queue.  The STAF command line utility works just like any other STAF application.  It registers with STAF, performs a request (which is the service request you specify), and then unregisters.  That last step causes the handle to be deleted.  Every time your run the STAF command line utility it gets a different handle.  When the process you started finishes, it tried to send the message to the queue of a handle that no longer existed.  If you were to do a queue list, you would be listing the queue of a completely different handle than the one that submitted the "process start" request.

If you were doing all of this inside a program, then it would have worked like you anticipated.  From the command line, you can simulate it by

  1. Open another window and have it use the delay command to wait for a while, for example

  2.     STAF local delay delay 300000
  3. See what handle the other window is using, for example

  4.         STAF local handle query all
    It should be the lowest numbered handle called "STAF/Client".
  5. Start the process and specify the specific handle to queue the message to, for example

  6.         STAF local process start command clock notify onend handle <handle_from_step_2>
  7. Stop the process, as you did previously
  8. Check the other window's queue, for example

  9.         STAF local queue list handle <handle_from_step_2>
Note, when the delay request finishes (after 5 minutes in this case), the handle and it's queue will disappear.


3.10 STAF machines can't communicate

If you are having problems getting two STAF machines to communicate, try the following steps on each machine:

On each machine, run "ping <other-machine hostname>" to determine if the machines can communicate.

On <machine1>, get the output from:

    staf local var resolve string {STAF/Config/Machine}

Then, on <machine2>, run:

    staf <machine1-var> ping ping

where <machine1-var> is the output from the "var resolve"

If the ping does not work (in either direction), then you need to update the DNS settings so that the machines can communicate.

On Windows 2000, to correctly set the DNS:

  1. From the "Start" menu, select "Network and Dialup Connections" and then select "Local Area Connection"
  2. Then click on "Properties" and select "Internet Protocol (TCP/IP)" and click on "Properties"
  3. Next, click on "Advanced" and make sure that the field for "DNS suffix for this connection:" shows the correct domain name (such as "austin.ibm.com")
  4. Another thing to verify is the Network Identification.  From the "Start" menu, select "Settings" and then "Control Panel"
  5. Next, select "System" and then select the "Network Identification" tab
  6. Then click on "Properties" and make sure that the "Computer name:" is correct
  7. Then click on "More" and make sure that the "Primary DNS suffix of this computer shows the correct domain name (such as "austin.ibm.com")
On Windows XP, to correctly set the DNS:
  1. From the "Start" menu, select "Network Connections" and then select your Local Area Connection
  2. Then click on "Properties" and select "Internet Protocol (TCP/IP)" and click on "Properties"
  3. Next, click on "Advanced" and then the "DNS" tab.  Make sure that the field for "DNS suffix for this connection:" shows the correct domain name (such as "austin.ibm.com")
  4. The second place to verify is the Computer Name.  From the "Start" menu, select "Control Panel"
  5. Next, select "System" and then select the "Computer Name" tab
  6. Then click on "Change" and make sure that the "Computer name:" is correct
  7. Then click on "More" and make sure that the "Primary DNS suffix of this computer" shows the correct domain name (such as "austin.ibm.com")
The following paragraph only applies to IBM users of STAF/STAX.  If you are running a Windows e-business client, and other machines can't ping the e-business client, it is likely that the e-business client is running "Net Firewall", which disables the ability of other machines to ping the e-business client (which also means that STAFProc on other machines will not be able to communicate with the e-business client).  To detemine if the machine is running Net Firewall, open the Network Connection the machine is using, and click on "Properties".  If "Net Firewall" is listed as a component, and it is checked, then the e-business client will experience this problem.  If you uncheck "Net Firewall" and click on OK, other machines will be able to ping the e-business client, and STAFProc on other machines will be able to communicate with the e-business client.  NOTE:  DO NOT UNINSTALL NET FIREWALL!  The AT&T Net Client will not run without Net Firewall, and if Net Firewall is uninstalled, you must completely reinstall the AT&T Net Client.

On Linux, to correctly set the DNS:

  1. Edit the /etc/sysconfig/network file and change the HOSTNAME line to:

  2.     HOSTNAME="pdxsg115.portland.ibm.com"
  3. and add the line:

  4.     DOMAINNAME="portland.ibm.com"
  5. reboot the machine
On HP-UX, to correctly set the DNS:
  1. Edit the /etc/rc.config.d/netconf file and change the HOSTNAME line to:

  2.     HOSTNAME="ex3b.austin.ibm.com"
  3. and add the line:

  4.     DOMAINNAME="austin.ibm.com"
  5. reboot the machine
Certain versions of Linux set up a high level of security access for incoming requests on specific ports (including STAF requests, which, by default, come in through port 6500).  From a Linux machine, if you are able to successfully send a "staf ping" to another machine, but the other machine cannot do a "staf ping" to the Linux machine (and you have verified that the DNS information is set up correctly on both machines), try the following (note that this example is for a RedHat 8.0 setup):
  1. Edit the /etc/sysconfig/iptables file and add the following line:

  2.    -A RH-Lokkit-0-50-INPUT -p tcp -m tcp --dport 6500 --syn -j ACCEPT
  3. Then execute:

  4.     /etc/rc.d/init.d/iptables restart

3.11 STAX still shows a process as running, even though it has completed

If you are running a STAX Job, and it shows that a process is still running, even though the process has actually completed, this is likely a DNS problem with either the STAX service machine or the machine where the process was executed (where the machine that executed the process is unable to find the STAX service machine in order to deliver the process completion message).

Refer to "Topic 10:  STAF machines can't communicate due to DNS issues" to resolve this problem.


3.12 RC 2 when starting the STAX Job Monitor

When starting the STAX Job Monitor, if you get an error message "Error registering Job Monitor.  Could not register for Job Events  RC = 2", this means that Event service name specified in the STAX Job Monitor Properties was not found on the specified Event machine.  In the main STAX Job Monitor window, click on File in the Menu bar, and then select Properties.  Make sure that the Event Service Name is the correct Event service name for the specified Event machine.  Also make sure that the Event service has been installed and configured on the Event service machine.


3.13 RC 16 when starting the STAX Job Monitor

When starting the STAX Job Monitor, if you get an error message "Error registering Job Monitor.  Could not register for Job Events  RC = 16", this means that Event service machine specified in the STAX Job Monitor Properties was not found.  In the main STAX Job Monitor window, click on File in the Menu bar, and then select Properties.  Make sure that the Event Service Machine is the correct Event service machine.


3.14 RC 2 when submitting new jobs through the STAX Job Monitor

When starting a new job through the STAX Job Monitor, if you get an error message "STAX Error.  RC:2  Error starting Job Monitor <STAX service name>", this means that STAX service name specified in the STAX Job Monitor Properties was not found on the specified STAX service machine.  The "<STAX service name>" in the error message is the STAX service name which would not be found.  In the main STAX Job Monitor window, click on File in the Menu bar, and then select Properties.  Make sure that the STAX Service Name is the correct STAX service name for the specified STAX service machine.  Also make sure that the STAX service has been installed and configured on the STAX service machine.


3.15 RC 16 when submitting new jobs through the STAX Job Monitor

When starting a new job through the STAX Job Monitor, if you get an error message "STAX Error.  RC:16  Error starting Job Monitor", this means that STAX service machine specified in the STAX Job Monitor Properties was not found.  In the main STAX Job Monitor window, click on File in the Menu bar, and then select Properties.  Make sure that the STAX Service Machine is the correct STAX service machine.


3.16 Process started successfully by STAF, but the process can't log its output to an AFS directory

When attempting to start a Process on a remote machine so that the output can be logged to an AFS directory, STAFProc needs to be started in an authenticated "session" in order to be able to store the log files in AFS-space.


3.17 STAF startup fails with 38:Illegal access to class: com.ibm.staf.service....

This error occurs if you attempt to register a Java service that has not been declared public in its class definition.  Every STAF Java service's class definition should look like:

    public class CronService implements STAFServiceInterfaceLevel3


3.18 Text files not converted correctly between Windows and Unix

Good news!  This has been resolved in STAF 2.5.0.  See the "File System (FS) Service" section of the STAF User's Guide for more information.


3.19 How to have multiple programs use a static handle to access variables and log data

If you have a program (PROG-A) that creates a static handle, and you want to start another program  (PROG-B) using the STAF start command, such that PROG-B can create variables and a log using that same handle. The problem is that each program has to know the number of the static handle in order to use it.  You can do this via an environment variable.  So, from PROG-A, you could do something like

    request = 'start command cmd.exe parms "/c PROG-B" env
    STAFHANDLE='staticHandle
    call STAFSubmit 'local', 'process', request

Then, PROG-B can pull the static handle from the environment.


3.20 If I edit a STAF log, it appears to be in some weird format

This is the expected format for STAF logs (they are binary files, not text files).  As a general rule you should use the Log service itself to look at the logs.  For example:

    STAF local log query global logname stresstst

You can redirect that to another file, which will be in text format, if you want.  You can also use the FmtLog utility (shipped with STAF) which will read a log file and format and write the data to an output file in a readable format.


3.21 STAF's user registration fails every time STAF is started

During the STAF installation, if you selected to register STAF, everytime STAF starts it will attempt to register the user information with a machine that is internal to IBM.  Once this registration is successful, STAF will  no longer try to register.  The registration will fail for all non-IBM users, and will attempt to register (and fail) each time STAF is started.  You can either choose to let it fail forever, or delete the STAFReg.inf file (in the root STAF directory) and STAF will stop trying to register.


3.22 When running STAFInst on Solaris, it fails with "test: unknown operator -ef"

If you receive this error message when running the command "./STAFInst" on Solaris, this indicates that the current Solaris shell does not support certain
"test" commands.  The solution for this problem is to enter "bash" at your shell prompt prior to entering "./STAFInst".


3.23 Running "java -jar STAXMon.jar" results in java.util.zip.ZipException

To run the command "java -jar STAXMon.jar", the STAXMon.jar file must be in the current directory (otherwise you will get the ZipException).  If it is not in the current directory, then you need to fully qualify the jar file name: "java -jar c:/staf/services/STAXMon.jar".


3.24 FS service COPY FILE fails when no TOMACHINE is specified

From machine m1 this command fails:

    c:\>staf m2 FS copy file c:/staf/data/log/global/temp.log tofile c:/staf/data/log/global/archivetemp.log
    Error submitting request, RC: 17
    Additional info: c:/staf/data/log/global/archivetemp.log

From machine m1 this command works:

    c:\>staf m2 FS copy file c:/staf/data/log/global/temp.log tofile c:/staf/data/log/global/archivetemp.log tomachine m2

This is working as expected/designed.  The default for the TOMACHINE option is the system that originated the request.  So, if 'm1' does not actually have a c:/staf/data/log/global directory, then STAF will not be able to create the archivetemp.log directory.  Once you add TOMACHINE m2, it is obvious you were trying to copy a file "locally" on the remote system, which does require the use of the TOMACHINE option.


3.25 Can't get Help on errors when STAF is not running

staf local help error <error number> doesn't work if STAF is not running on your workstation.  Users can access help messages offline (when STAF isn't running) by viewing the STAF documentation.  STAF documentation is installed on the local system (if a typical install was done).  The "STAF API Return Code Reference" contains a quick reference to the STAF return codes and is available at staf/docs/STAFRC.htm or you can view it on the STAF SourceForge website at http://staf.sourceforge.net/v2.4.2/STAFRC.htm.


3.26 STAX Job Monitor window doesn't have a close confirmation

Closing the STAX Job Monitor window should never terminate your job.  Doing that just closes that view of the job; the STAX job should still be running.  In the main STAX Monitor window (which shows the table of currently running STAX jobs), your job still should be there, and you should be able to right click on it and select "Start Monitoring", and you should see a new STAX Job Monitor window for your STAX job.


3.27 Why are there are more STAF processes on Linux?

If you issue the following command

    ps -ef | grep -i staf

You will see more STAFProc processes (typically 10 or more) on Linux than other platforms (which there's only one).

This is because the Linux base operating system doesn't really have threads.  Threads are simulated on Linux using processes, so each thread shows up as a process.


3.28 The Echo, Ping, and Delay services do not provide help

The simple STAF services (Echo, Ping, Delay) all have just one option (the same name as the service) and have
never provided a HELP option.  The syntax for these services is documented in the STAF User's Guide and the
Service Command Reference at http://staf.sourceforge.net/current/STAFCMDS.htm.


3.29 HP-UX SIGABRT after a STAF process has completed

If you see the following error on an HP-UX machine after a STAF process has completed:

Received signal 6 (SIGABRT)
/usr/lib/dld.sl: Call to __sigenable() failed
/usr/lib/dld.sl: Not owner
Received signal 6 (SIGABRT)
/usr/lib/dld.sl: Unresolved symbol: __h_errno__Fv (code)  from
/usr/local/staf/l
ib/libSTAF.sl
Received signal 6 (SIGABRT)
/usr/lib/dld.sl: Call to __sigenable() failed
/usr/lib/dld.sl: Not owner
Received signal 6 (SIGABRT)
/usr/lib/dld.sl: Unresolved symbol: __h_errno__Fv (code)  from
/usr/local/staf/l

This is likely due to an incorrect hostname.  Verify that the DNS is setup correctly an all machines (Refer to "Topic 10:  STAF machines can't communicate due to DNS issues").


3.30 Error initializing service, RESPOOL, RC: 4008

The ResPool RC 4008 means "The directory specified by the DIRECTORY parameter when registering the service or the default directory could not be created."

It is likely that STAF was installed as another userid, and you are now trying to use the ResPool as a different userid that doesn't have write access to the STAF directory.



3.31 Unix error message: "STAFProcessManager::processMonitorThread: Parent could not set child's pgid: 13"

Periodically on Unix systems you may see this error message.  You can ignore these messages (you should not encounter any problems because of the messages).


3.32 Email service SEND request results in RC 7 when quotes or double quotes are in the message

If the message request had embedded quotes or double quotes, it may cause the STAF command parsing to fail (resulting in the RC 7).  Here is a portion of a STAX job that shows how to get this working:

  <script>
    from com.ibm.staf import STAFUtil
    emailmessage = STAFUtil.wrapData(emailmessage)
  </script>

  <stafcmd>
   <location> 'local' </location>
   <service> 'email' </service>
   <request> 'send to user@us.ibm.com message %s"' %(emailmessage)</request>
  </stafcmd>

  <if expr="RC !=0">
    <message>"RC: %s result: %s" % (RC, STAFResult)</message>
  </if>


3.33 Child processes are not killed on Windows

If you terminate a STAX job (or send a Process Stop request to a running STAF process) on Windows, any child processes that the process has created will not be terminated.  This is a limitation on Windows platforms.  To resolve this problem you can specify the option: "STOPUSING WM_CLOSE" on the PROCESS START request, or specify the <stopusing>'WM_CLOSE'</stopusing> element for a STAX <process> element.


3.34 "JAR Archive failed security check corrupt JAR file" message after downloading a STAF jar file

Certain browsers may report this problem when downloading jar files.  To resolve the problem, "shift-click" on the link to download the jar file.


3.35 RC=10 and STAFResult=8 when starting a Java process in a STAX job

Certain Unix Java versions will contain a /bin/java file that is actually a soft link to a wrapper shell script file, rather than a binary executable file.  If you try to start a Java process in a STAX job:

     <command>'java'</command>

the result will be RC=10 and STAFResult=8.  The Operating System return code 8 indicates "Exec format error".  To resolve this problem, specify the 'shell' attribute:

    <command mode="'shell'">'java -version'</command>


3.36 Changes to imported Python module not picked up in STAX job

Use the built-in Python "reload" function if you want to pick up changes made to imported Python modules without having to unregister and register the STAX service (either by stopping STAF and restarting it or by using the SERVICE service to dynamically delete and add the STAX service). Note that there is a "gotcha" in that reload may not impact "from" imports. Reloading allows you to test Python module changes immediately after reloads, without having to unregister the STAX service. Here's more detailed information about using the built-in Python "reload" function.

One of the most common questions Python beginners seem to ask when using modules is: why won't my imports keep working? The first import works fine, but later imports in STAX jobs seem to have no effect. They're not suppposed to, and here's why:

Python loads, compiles, and runs code in a module file only on the first import, on purpose; since this is an expensive operation. So, even across STAX jobs, a Python module's code is run only once per STAX service by default. But, sometimes you really want a module's code to be rerun.

To force a module's code to be reloaded and rerun, you need to ask Python explicitly to do so, by calling the reload built-in function. Using reload can make your STAX jobs more dynamic. In a nutshell:

Unlike import and from: Because reload expects an object, a module must have been previously imported successfully before you can reload it. Reloading looks like this:
  import module     # initial import
  #  Use module.attributes
  ...               # now, go change the module file
  ...
  reload(module)    # get updated exports
  # Use module.attributes
You typically import a module, then change its source code in a text editor and reload. When you call reload, Python rereads the module file's source code and reruns its top-level statements and changes a module object in-place, so every referenece to a module object is automatically effected by a reload.

Note that there is an important "gotcha" in that reload may not impact from imports. In fact, the from statement is the source of all sorts of gotchas in Python. Because from copies (assigns) names when run, there's no link back to the module where the names came from. Names imported with from simply become references to objects, which happen to have been referenced by the same names in the importee when the from ran. Because of this behavior, reloading the importee has no effect on clients that use from; the client's names still reference the objects fetched with from, even though names in the original module have been reset. For example:

  from module import X     # X may not reflect any module reloads!
  ...
  reload(module)           # changes module, not my names
  X                        # still references old object
The solution to this is: Don't do it that way. To make reloads more effective, use import and name qualification, instead of from. Because qualifications always go back to the module, they will find the new bindings of module names after calling reload:
  import module            # get module, not names
  ...
  reload(module)           # changes module in-place
  module.X                 # get current X; reflects module reloads
So, let's say you have a Python file, changer.py, in directory /usr/mypyfuns that contains a function called getValue. For example, say changer.py looks like:
value = 'First value'

def getValue():
    return value
Here's an example of a STAX job that tests reloading function getValue from module changer in /usr/mypyfuns. If you run this job, even after editing changer.py so that value is assigned some other value, you'll get the updated value.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE stax SYSTEM "stax.dtd"> 

<!--  Test reloading Python modules-->

<stax>

  <defaultcall function="TestReload"/> 

  <script>
    myPythonDir = '/usr/mypyfuns'

    import sys
    pythonpath = sys.path

    # Append myPythonDir to sys.path if not already present
    if myPythonDir not in pythonpath:
      sys.path.append(myPythonDir)

    # Import
    import changer

    # Force new code to load/run
    reload(changer)
  </script>

  <function name="TestReload">
    <message>'changer.getValue()=%s' % changer.getValue()</message>
  </function> 

</stax>
See Python documentation for more information about module reloads.


3.37 Does the HTTP Service retain session information across multiple requests?

The HTTP service is simply a wrapper around some very simple Java code which creates an  HttpURLConnection to the specified URL.  For the HTTP methods GET, HEAD, OPTIONS, DELETE, and TRACE it simply makes the appropriate connection and returns responseCode and responseMessage, and creates an inputStream from the connection and reads from it.  All of this information is then used to create the STAF RC and Result Buffer.  For POST and PUT methods, the connection is made and an OutputStream is created for the connection.  The value of the CONTENT parameter is then written to the output stream.  The rest of the processing occurs as for the "retrieval" HTTP methods above.  So, no state information is kept between requests.  Each request creates a new HttpURLConnection.


3.38 Unix error message: STAFProcessManager::processMonitorThread: Could not start process (execve): 8

If you get this error message when trying to start a process on a Unix system, the 8 in the error message is the errno that is being set by the operating system. For example, an errno of 8 on a Solaris 5.7 system, according to the /usr/include/sys/errno.h file, means "Exec format error". This indicates that there is a problem with the executable you specified in the process start command. If you specified a shell script, check to see if it is missing #! on the first line. Check if you can execute the same command (and parameters, if specified) without involving STAF.


3.39 Problems accessing a Java service, such as RC=6

If you are having a problem accessing a Java service, such as getting an RC 6 for any request you make to a Java service, the Java service's JVM may have encountered an error or may have been killed. Check the Java service's JVM log to see if any errors were logged. The JVM logs are stored in the {STAF/Config/STAFRoot}/data/JSTAF/<JVMName> directory on the system where the Java service is registered. The current JVM log is named JVMLog.1.

If the JVM log contains an OutOfMemory error, any Java services using this JVM will have to be removed and added (registered) in order to start accepting requests. You may want to look at increasing the JVM's maximum heap size as the Java service(s) using this JVM may require more memory than can be allocated. Refer to the STAF User's Guide, section "4.4.3 JSTAF service proxy library", for more information on how to do this.

If the JVM was killed, there won't be errors regarding this in the JVM log, but the following error is written to the STAFProc window when a request is made to a Java service whose java executable has died:

In JSTAF.STAFServiceAcceptRequest: 
Caught STAFException 
Name : STAFConnectionConnectException 
Location : d:\dev\sf\src\staf\stafif\win32\STAFLocalConnection.cpp(162) 
Text : OpenProcess2 
Error code: 87
If the JVM was killed, any Java services using this JVM will have to be removed and added (registered) in order to start accepting requests.


3.40 On some Unix platforms (such as Solaris), exiting the STAFProc terminal causes STAF to terminate

For example, if you have a script such as:

   PATH=/usr/local/staf/bin:/usr/local/java/bin:$PATH
   export PATH
   CLASSPATH=/usr/local/staf/lib:/usr/local/staf/lib/JSTAF.jar:$CLASSPATH
   export CLASSPATH
   STAFCONVDIR=/usr/local/staf/codepage
   export STAFCONVDIR
   LD_LIBRARY_PATH=/usr/local/staf/lib:$LD_LIBRARY_PATH
   export LD_LIBRARY_PATH

   /usr/local/staf/bin/STAFProc &

STAF will start fine if you log in and exec this script, but when you log out, STAF terminates.

To resolve this you should change the last line in the script to:

   nohup /usr/local/staf/bin/STAFProc &

# man nohup

NAME
     nohup - run a command immune to hangups

SYNOPSIS
     /usr/bin/nohup command [ argument ...]
     /usr/xpg4/bin/nohup command [ argument ...]

DESCRIPTION
     The nohup utility invokes the named command with  the  argu-
     ments supplied.  When the command is invoked, nohup arranges
     for the SIGHUP signal to be ignored by the process.

     The nohup utility can be used when it is known that  command
     will take a long time to run and the user wants to logout of
     the terminal; when a shell exits, the system sends its chil-
     dren  SIGHUP  signals,  which  by  default  cause them to be
     killed.  All stopped,  running,  and  background  jobs  will
     ignore  SIGHUP  and continue running, if their invocation is
     preceded by the nohup command or if the process programmati-
     cally has chosen to ignore SIGHUP.


3.41 How do you access system date and time in STAX?

You can either use the python libraries or the java libraries.  Here is a STAX job which shows both approaches:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>

  <defaultcall function="test"/>

  <function name="test">

    <sequence>

      <!-- get the python date -->
      <script>
        from time import localtime, strftime
        currenttime = strftime("%a, %d %b %Y %H:%M:%S", localtime())
      </script>

      <message>'Python time: %s' % currenttime</message>

      <!-- get the java date -->
      <script>
        from java.util import Calendar, Date
        from java.text import SimpleDateFormat
        formatter = SimpleDateFormat("yyyy.MM.dd G 'at' hh:mm:ss a zzz")
        currentTimestamp = Date()
        dateString = formatter.format(currentTimestamp)
      </script>

      <message>'Java time: %s' % dateString</message>

    </sequence>

  </function>

</stax>


3.42 Are there any conflict or efficiency concerns with using STAX <import> when doing nested file imports?

Question: If I have a situation where file A imports files B and C, and files B and C both import file D is that going to cause any sort of conflict when a call is made to a function in file D?

Answer: No.

Second: If file A imports file B and file B imports file C, does file C get re-imported every time the function in file B is called?  If so is there any potential conflict there, and how much will this impact overall efficiency?

Answer: No, functions in file C do not get re-imported every time the function in file B is called.  However, we should point out that file C will, in fact, be reimported every time.  Now, none of the functions in it will get imported, but the file will be retrieved and parsed each time you try to import something from it.  Depending on how big this file is, and how often you are calling the function which imports it, you might either set a STAF variable (with the job number somewhere in it) that you can retrieve across function calls, or have the importing function use "global" scope and set a STAX variable that indicates the import has already been done.

You can see this for yourself if you'd like by looinkg at STAXResult after each <import> element.  In the STAX User's Guide, in the section that describes the <import> element, it says:

"After executing an import element, STAXResult will be set to a list containing:

- STAXResult[0]: Either None or a list containing a STAXImportError object and a text string with details about the error.
- STAXResult[1]: A list of the successfully imported functions that were requested to be imported.
- STAXResult[2]: A list of the successfully imported functions that were required by other functions.
- STAXResult[3]: A list of the functions that were requested to be imported but already existed (so they were not imported).
- STAXResult[4]: A list of the functions that were required by other functions but already existed (so they were not imported).
- STAXResult[5]: A list of the functions that were not requested to be imported and were not required by other functions.
- STAXResult[6]: A list of functions requested to be imported that were not found."

Here are some STAX jobs that demonstrate this:

Here is the contents of D:/dev/src/stax/A.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>
  <defaultcall function="FunctionA"/>

  <script>
    machName = 'lucas'
  </script>

  <function name="FunctionA">
    <sequence>

      <message>'Running FunctionA'</message>

      <import machine="machName" file="'D:/dev/src/stax/B.xml'" mode="'error'"/>

      <message>
        'After import B.xml:\n%s\n%s\n%s\n%s\n%s\n%s\n%s' % \
        (STAXResult[0], STAXResult[1], STAXResult[2], STAXResult[3], STAXResult[4],
         STAXResult[5], STAXResult[6])
      </message>

      <call function="'FunctionB'"/>
      <call function="'FunctionB'"/>
      <call function="'FunctionB'"/>

    </sequence>
  </function>

</stax>

Here is the contents of D:/dev/src/stax/B.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>

  <function name="FunctionB">
    <sequence>

      <message>'Running FunctionB'</message>

      <import machine="machName" file="'D:/dev/src/stax/C.xml'" mode="'error'"/>

      <message>
        'After import C.xml:\n%s\n%s\n%s\n%s\n%s\n%s\n%s' % \
        (STAXResult[0], STAXResult[1], STAXResult[2], STAXResult[3], STAXResult[4],
         STAXResult[5], STAXResult[6])
      </message>

    </sequence>
  </function>

</stax>

Here is the contents of D:/dev/src/stax/C.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>

  <function name="FunctionC">
    <sequence>

      <message>'Running FunctionC'</message>

    </sequence>
  </function>

</stax>

Here are the results that were logged.  As you can see, the second and third time that FunctionB was called, the STAXResult after
importing C.xml in FunctionB shows 'FunctionC' showing up in STAXResult[3] instead of STAXResult[1].

STAXResult[1] is a list of the successfully imported functions that were requested to be imported.
STAXResult[3]: A list of the functions that were requested to be imported but already existed (so they were not imported).

D:\>staf local log query machine lucas logname STAX_Job_11_User
Response
--------
20030319-18:52:10|lucas|189|STAX/Job/11|Info|Running FunctionA
20030319-18:52:11|lucas|189|STAX/Job/11|Info|After import B.xml:
None
['FunctionB']
[]
[]
[]
[]
[]
20030319-18:52:11|lucas|189|STAX/Job/11|Info|Running FunctionB
20030319-18:52:11|lucas|189|STAX/Job/11|Info|After import C.xml:
None
['FunctionC']
[]
[]
[]
[]
[]
20030319-18:52:11|lucas|189|STAX/Job/11|Info|Running FunctionB
20030319-18:52:11|lucas|189|STAX/Job/11|Info|After import C.xml:
None
[]
[]
['FunctionC']
[]
[]
[]
20030319-18:52:11|lucas|189|STAX/Job/11|Info|Running FunctionB
20030319-18:52:11|lucas|189|STAX/Job/11|Info|After import C.xml:
None
[]
[]
['FunctionC']
[]
[]
[]


3.43 Can you use the <stopusing> element in a STAX job that runs on both Windows and Unix?

Yes.  You can first determine whether the machine is Windows or non-Windows, set a variable to the STOPUSING option that you want to use on that operating system, and then use that variable in the <stopusing> element.  Here is a sample STAX job:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>

  <defaultcall function="test"/>

  <function name="test">

    <sequence>

      <stafcmd>
        <location>'local'</location>
        <service>'var'</service>
        <request>'resolve string {STAF/Config/OS/Name}'</request>
      </stafcmd>

      <script>
        import re
        osname = STAFResult
      </script>

      <if expr='re.search("^win", osname.lower()) != None'>
        <script>stopusing = 'WM_CLOSE'</script>
        <else>
          <script>stopusing = 'SIGKILLALL'</script>
        </else>
      </if>

      <process>
        <location>'local'</location>
        <command>'java'</command>
        <stopusing>stopusing</stopusing>
      </process>

    </sequence>

  </function>

</stax>


3.44 How do I find out more information about Python?

Main Python doc page:
http://www.python.org/doc/

Library reference:
http://www.python.org/doc/current/lib/lib.html

Language reference:
http://www.python.org/doc/current/ref/ref.html

Info on re:
http://www.python.org/doc/current/lib/module-re.html

Info on import:
http://www.python.org/doc/current/ref/import.html

Python book reviews:
http://www.awaretek.com/book.html


3.45 In recent versions of STAF, I no longer see any Java service output in the STAFProc console

The console output was redirected because in STAF 2.4.4 we changed the way JVMs for STAF Java services (such as STAX) output all of their stdout/stderr data (including the output of <script>print...</script> since that is being written to the JVM's stdout). All of the output that was formerly in the console output should now be in the JVMLog file. The file is located at:

    {STAFRoot}/data/JSTAF/<JVM Name, default: STAFJVM1>/JVMLog.x

where x is a number.

If you look at your c:/staf/data/JSTAF/STAFJVM1/JVMLog.1 file, you should see something like:

    ******************************************************************************
    *** 20030418-14:40:33 - Start of Log for JVMName: STAFJVM1
    *** JVM Executable: java
    *** JVM Options : none
    ******************************************************************************


3.46 When importing a STAX function from another XML file, are the global <script>s in the XML file executed?

Global <script> elements defined in an XML file containing only functions intended to be imported by the <import> element, are not recognized in the body of the functions.
In the imported xml file, only the <script> elements contained within the imported <function> will be executed.

Just to give a little history, in the early stages of STAX's life, <function>s were not allowed to take arguments (and the <import> element didn't exist either). Any data that you wanted to "pass into" a function had to be previously set in existing variables. To that end, it was necessary to allow <script> elements at the root of the document so that default values could be fed into the functions.  However, once we added argument passing to <function>s, we began encouraging that over global <script>s.   Nevertheless, we couldn't remove support for global <script>s, as many groups were already using them.

When we implemented the <import> element, we felt it would be cleaner to just import the <function>s in the job, as there was less interaction with the pieces of the importing job. For example, what you already had a variable that was overwritten by a <script> in another file, just because you imported a single utility <function> from it. Even if you were expecting a certain variable to be set from the job, you would have to be very careful to import the functions in the job first, and then set the variables, otherwise your values would overwritten. This same line of argument also applies to importing <signalhandler>s.


3.47 Are STAF system variable values available in STAX?

Yes, but not directly. The STAF variables have to be resolved using either the VAR service through a <stafcmd> or using the STAXUtilImportSTAFVars function from the STAXUtil.xml file (provided with the STAX download in the library subdirectory of the STAX installroot).

Examples:

Using stafcmd to call the var service

    <stafcmd>
      <location>'local'</location>
      <service>'var'</service>
      <request>'resolve string {STAF/Config/STAFRoot}'</request>
    </stafcmd>
    <script>stafRoot=STAFResult</script>

Using STAXUtilImportSTAFVars

    <call function="'STAXUtilImportSTAFVars'">
      [
        {'STAF/Env/STAFDir': 'mySTAFDir', 'STAF/Version': 'mySTAFVersion'},
        'machA'
      ]
    </call>

and the resulting STAX variables could be:
mySTAFDir = 'C:\STAF'
mySTAFVersion = '2.5.0'

See STAXUtil.html for full details.
 


3.48 How do you search for multiple strings in testcase output files in STAX?

You can use the Python re library to search for multiple strings in testcase output files.  For example, if you have a testcase output file c:/temp/test.txt:

********************************* Top of Data **********************************
---------+---------+---------+---------+---------+---------+---------+---------+
   SET CURRENT SQLID='DBTIFAHC';
---------+---------+---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+---------+---------+
   SELECT * FROM SPA_FI_REGISTRY;
---------+---------+---------+---------+---------+---------+---------+---------+
FI_ID     AVLBLTY_STATUS  UPDATE_USER_ID  UPDATE_TMSTP
---------+---------+---------+---------+---------+---------+---------+---------+
IBANKA    S               STCCICS         2003-07-11-08.38.37.638163
DSNE610I NUMBER OF ROWS DISPLAYED IS 1
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
---------+---------+---------+---------+---------+---------+---------+---------+
-- INSERT INTO IFS_SESSN_ACTIVE
--   (USR_ID, FI_ID,SERV_ID,SESSN_NBR,IP_ADDR,SESSN_STRT_TMSTP,
--    SESSN_END_TMSTP,SESSN_ST_CODE, SESSN_MQ_QUALIFIER,CHK_DUPL_TXN,
--    SERV_INST_NBR)
  F1=Help    F2=Split   F3=Exit    F5=Rfind   F7=Up      F8=Down    F9=Swap
 F10=Left   F11=Right  F12=Cancel
                            SPUFI                              SSID: DB71
 ===>

 Enter the input data set name:        (Can be sequential or partitioned)
  1  DATA SET NAME ... ===> 'MONICA1.IFSSCCAH.SPUFI.CNTL(SELECT)'
  2  VOLUME SERIAL ... ===>            (Enter if not cataloged)
  3  DATA SET PASSWORD ===>            (Enter if password protected)
                    ³ DSNE361I SPUFI PROCESSING COMPLETE ³
 
Here's a sample STAX job that searches for 3 sets of strings in the test.txt file.

Notice that when you specify the string text, you need to escape, with a backslash, any non-alphanumeric characters (such as spaces, dots, comma, equals, greater/less than, paraenthesis...).  You can find a Howto on Regular Expressions at http://www.amk.ca/python/howto/regex/

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>

  <defaultcall function="test"/>

  <function name="test">

    <sequence>

      <stafcmd>
        <location>'local'</location>
        <service>'fs'</service>
        <request>'get file c:/temp/test.txt'</request>
      </stafcmd>

      <script>
        import re
        result = STAFResult

        searchre = r"""(?mx)
                       ^.*
                       ^.*?IBANKA.*?
                       ^.*
                       ^.*?1\ \ DATA\ SET\ NAME\ \.\.\.\ \=\=\=\>\ \'MONICA1\.IFSSCCAH\.SPUFI\.CNTL\(SELECT\)\'.*?
                       ^.*
                       ^.*?DSNE361I\ SPUFI\ PROCESSING\ COMPLETE.*?
                       ^.*"""
      </script>

      <if expr='re.match(searchre, result) != None'>
        <message>'Pass'</message>
        <else>
          <message>'Fail'</message>
        </else>
      </if>

    </sequence>

  </function>

</stax>



3.49 Can you use STAF and STAX with VMWare images?

Yes, you can use STAF/STAX to boot VMWare images and then execute tests on the VMWare images.  Below is a example that demonstrates how to do this.  The "startvmware" function boots a VMWare image.  Note that it's <function-prolog> has important information on how to configure your VMWare image to work correctly with STAF/STAX.  The "stopvmware" function shuts down and powers off a VMWare image.  The "main" function shows how you call the vmware functions.  In your main function, after the VMWare image has booted (you would need to wait for an appropriate amount of time and do a STAF PING to the machine to determine that it's up and running), you would begin running your tests on the VMWare image.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">

<stax>
 
  <defaultcall function="main"/>
 
  <function name="main" scope="local">
 
    <parallel>

      <block name="'Boot up VMWare image'">
        <call function="'startvmware'">
          { 'image' : 'c:/vmware/winxp/Windows-XP-Professional.vmx',
            'timeout' : '5m',
            'imagehostname' : 'abcdef',
            'imagename' : 'Windows XP Professional'
          }
        </call>
      </block>
 
      <block name="'Release this block to shutdown the VMWare image'">
        <sequence>
 
          <hold/>
 
          <call function="'stopvmware'">
            { 'imagehostname' : 'abcdef',
              'shutdown' : 'shutdown -s -f -t 0'
            }
          </call>

        </sequence>
      </block>
 
    </parallel>

  </function>
 
  <function name="startvmware" scope="local">
 
    <function-prolog>
      Starts a VMWare image, and attempts to do a STAF PING to the VMWare image.
      Your VMWare image needs to be configured so that there are no popups
      displayed when the VMWare image starts (for example, messages about Disk
      Drive warnings, etc), and that the image is set up to automatically log
      in.  Also, the machine must be configured to start STAF automatically.
      Also, you must have the following 2 lines in your VMWare image's .vmx file:
 
      gui.exitOnCLIHLT = "TRUE"
      gui.exitAtPowerOff = "TRUE"
 
      Note that you should avoid terminating any blocks that are running a VMWare
      image, as that will kill the VMWare image without it being shutdown.  Instead,
      you should manually shutdown and power off the VMWare image, or call the
      "terminatevmware" [not yet implemented] function.
 
      You should use Bridged network connections for VMWare images to work
      correctly with this function.
    </function-prolog>

    <function-map-args>
 
      <function-optional-arg name="machine" default="'local'">
        The machine on which the VMWare image is to be started.  The default is 'local'.
      </function-optional-arg>
 
      <function-optional-arg name="vmwarebin" default="'c:/Program Files/Vmware/VMware Workstation/vmware.exe'">
        The VMWare executable file.  If the VMWare executable is not in the VMWare system's PATH, then the file
        must be fully qualified.  The default is 'c:/Program Files/Vmware/VMware Workstation/vmware.exe'.
      </function-optional-arg>
 
      <function-required-arg name="image">
        The fully qualified VMWare .vmx file for the VMWare image.  Note that the VMWare executable
        does not permit spaces in the file name of the .vmx file.
      </function-required-arg>
 
      <function-required-arg name="imagehostname">
        The hostname for the VMWare image.
      </function-required-arg>
 
      <function-optional-arg name="timeout" default="'10m'">
        The timeout value for when the function should stop attempting to STAF PING the VMWare image.  The
        default is 10 minutes.  The STAF PING to the VMWare image will be attempted every 30 seconds, up to
        the timeout value.
      </function-optional-arg>
 
      <function-optional-arg name="imagename" default='image'>
        The name of the VMWare image.  The default is the argument specified for image.
      </function-optional-arg>
 
    </function-map-args>

    <parallel>
 
      <process name="'VMWare Image %s ' % imagename">
        <location>machine</location>
        <command>vmwarebin</command>
        <parms>'-x -q %s' % image</parms>  <!-- -x powers on automatically, -q exits at power off -->
        <stdout>'out.txt'</stdout>
        <stderr mode="'stdout'"/>
        <returnstdout/>
      </process>

      <sequence>

        <script>contacted = 0</script>
 
        <timer duration='timeout'>

          <loop while="contacted == 0">

            <sequence>
 
              <stafcmd name="'Delaying for 30 seconds'">
                <location>'local'</location>
                <service>'delay'</service>
                <request>'delay 30000'</request>
              </stafcmd>
 
              <stafcmd name = "'Attempt to ping %s' % imagehostname">
                <location>imagehostname</location>
                <service>'ping'</service>
                <request>'ping'</request>
              </stafcmd>
 
              <if expr="RC == 0">
                <sequence>
                  <script>contacted = 1</script>
                  <message>'Machine %s is up and running with VMWare image %s' % (imagehostname, imagename)</message>
                  <log>'Machine %s is up and running with VMWare image %s' % (imagehostname, imagename)</log>
                </sequence>
              </if>

            </sequence>
 
          </loop>

        </timer>
 
        <if expr="RC != 0">
          <sequence>
            <message>'Machine %s with VMWare image %s was not successfully started RC: %s' % (imagehostname, imagename, RC)</message>
            <log>'Machine %s with VMWare image %s was not successfully started RC: %s' % (imagehostname, imagename, RC)</log>
          </sequence>
        </if>
 
      </sequence>
 
    </parallel>

  </function>
 
  <function name="stopvmware" scope="local">
 
    <function-prolog>
      Stops a VMWare image
    </function-prolog>

    <function-map-args>
 
      <function-required-arg name="imagehostname">
        The hostname for the VMWare image.
      </function-required-arg>
 
      <function-required-arg name="shutdown">
        The command used to shut down the OS.
      </function-required-arg>
 
    </function-map-args>

    <sequence>
 
      <script>
          from com.ibm.staf import STAFUtil
      </script>
 
      <stafcmd>
        <location>imagehostname</location>
        <service>'process'</service>
        <request>'start async shell command %s' % STAFUtil.wrapData(shutdown)</request>
      </stafcmd>

    </sequence>
 
  </function>

</stax>



3.50 Does a STAX process element use the workdir element as the path to the command?

No. The STAF User's Guide, section 8.10.2 (PROCESS START) says:

COMMAND specifies the actual command that you want to start. If the path to the command is not specified, the system PATH will be searched for the command.

So, if the path to the command is not specified in the <command> element, the system PATH is searched. Just specifying the <workdir> will not make it use the workdir as the path and you'll get RC 10 (Base operating system error) because it couldn't find the command executable.

The following <process> element specifies the path (assigned to variable testdir) to the test1.exe executable since it's not in the system PATH:

  <script>
    clientname = 'machineA.austin.ibm.com'
    testdir = 'C:/test'
  </script>

  <process>
    <location>clientname</location>
    <command>'%s/test1.exe' % (testdir)</command>
    <workdir>testdir</workdir>
  </process>


3.51 Why am I getting a java.lang.NullPointerException at org.python.core.ThreadState.entrRepr in my JVMLog.1 file?

The following NullPointerException at org.python.core.ThreadState.enterRepr(ThreadState.java) is a known problem in IBM Java's JIT:

******************************************************************************
*** 20030911-12:50:41 - Start of Log for JVMName: STAFJVM1
*** JVM Executable: java
*** JVM Options   : -Xms128m -Xmx512m
******************************************************************************
java.lang.NullPointerException
	at org.python.core.ThreadState.enterRepr(ThreadState.java(Compiled Code))
	at org.python.core.PyList.toString(PyList.java(Compiled Code))
	at org.python.core.PyObject.__repr__(PyObject.java(Compiled Code))
	at org.python.core.PyObject.__str__(PyObject.java(Compiled Code))
	at com.ibm.staf.service.stax.STAXThread.pyStringEval(STAXThread.java(Compiled Code))
	at com.ibm.staf.service.stax.STAXMessageAction.execute(STAXMessageAction.java(Compiled Code))
	at com.ibm.staf.service.stax.STAXThread.execute(STAXThread.java(Compiled Code))
	at com.ibm.staf.service.stax.STAXThreadQueue$QueueThread.run(STAXThreadQueue.java:66)
If you see this NullPointerException in your JVMLog.1 file when debugging a problem running a STAX job, verify that the JVM that STAX is using is IBM's java by doing:
  java -version
This problem is in the JIT in IBM Java versions 1.3.x, 1.4.0, and 1.4.1 and has been seen on both Windows and Unix systems. This problem has been reported to IBM Java support and is under investigation. When this NullPointerException occurs in the JVM, any services using this JVM can no longer function until the services using this JVM are removed and re-added via the SERVICE service or STAFProc is shutdown and restarted.

There are two workarounds:

  1. Disable the JIT (which will degrade performance).

    To turn the JIT off for the JVM that the STAX service is using, configure the STAX service using a J2 OPTION to set the java.compiler property to NONE. For example:

        SERVICE STAX LIBRARY JSTAF EXECUTE C:\STAF\services\STAX.jar \
                     OPTION JVMName=STAX OPTION J2=-Xmx256m \
                     OPTION J2=-Djava.compiler=NONE

  2. Use another version of Java (e.g. Sun Java) instead.

    To specify another version of Java for the STAX service to use, configure the STAX service using the JVM OPTION to set the Java executable. For example, if you install Sun Java 1.4.1 in C:\sunjdk1.4.1, then configure STAX as follows to specify to use the java executable in the C:\sunjdk1.4.1\bin directory:

        SERVICE STAX LIBRARY JSTAF EXECUTE C:\STAF\services\STAX.jar \
                     OPTION JVM=C:\sunjdk1.4.1\bin\java \
                     OPTION JVMName=STAX OPTION J2=-Xmx512m


4. GLOBALIZATION



4.1 How do I use STAF/STAX in environments where machines running STAF have different locales?

In general, you don't have to do anything special.

The requests submitted to STAF and the results received from STAF are all strings. These strings may contain any arbitrary set of characters, including the NULL (i.e., 0) character. When working in an environment with a heterogeneous set of codepages, STAF will translate the request and result strings from and to the necessary codepages. This ensures that the request and result strings are not misinterpreted by the receiver.

In general, when using STAF services, there shouldn't be any round trip problems. "Round trip" in this context means when all requests are originating from the same system, even if the requests are sent to, and the data is stored on, a system with a different codepage. However, if you send, for example, a request to log data containing Japanese codepage specific characters to any system and then query the log from a system using a US English codepage, you won't get the "correct" data, as that is not a valid "round trip".

Note: All STAF generated strings are composed of only ASCII-7 characters and will safely survive the translation from/to different codepages.

Caution:

If you use a STAF service that is written in REXX, it can have round trip codepage translation problems. All of STAF services currently provided are written in C++/Java so they do not have this problem.



4.2 How do I specify non-ASCII characters in a STAF request or STAX job?

If you're specifying a STAF request from the command line, then you can just specify the appropriate characters. For example, here's a STAF request submitted via the command line specifying a French character in the PARMS value:

STAF frenchMach PROCESS START COMMAND c:/test/TestA PARMS "-server français"

If you want to specify non-ASCII characters in a STAX job, then you need to specify them in Unicode. For example, here's a process element which specifies a French character in Unicode in the <parms> element:

  <process>
    <location>'frenchMach'</location>
    <command>'c:/test/TestA'</command>
    <parms>'-server fran' + u'\u00E7' + 'ais'</parms>
  </process>
Here's an example of a stafcmd element which specifies Chinese characters in Unicode for the directory name in a STAX job:
  <script>dirName = '/tmp/Sun2_' + u'\u4F3A\u670D\u5668'</script>

  <stafcmd>
    <location>'chineseMach'</location>
    <service>'FS'</service>
    <request>'CREATE DIRECTORY %s' % (dirName)</request>
  </stafcmd>

If you want to specify non-ASCII characters in a STAF request submitted via a Java program, then you need to specify them in Unicode. Here's an example of specifying Chinese characters in Unicode in a PROCESS START request submitted via a Java program:

  String machine    = "chineseMach";
  String service    = "PROCESS";
  String serverName = "\u4F3A\u670D\u5668_HP";
  String request    = "START COMMAND " + STAFUtil.wrapData("/test/startServer.sh") +
                      " PARMS " + STAFUtil.wrapData(serverName) + " WAIT";
  STAFResult submitResult = handle.submit2(machine, service, request);

If you need to specify non-ASCII characters in a request, then you need to be aware of some anomalies if your target system is a Windows system that isn't using an English codepage and whose ANSI codepage (ACP) identifier is different from the OEM codepage (OEMCP) identifier. The system locale determines which codepages are defaults for the Windows system. However, some European locales such as French and German set different values for the ACP and OEMCP. See section "2.7.1 Windows Codepage Translation Anomalies" in the STAF User's Guide for more information on these Windows codepage translation anomalies.



4.3 How do I know what codepage STAF is using on my machine?

To see the codepage that STAF is using, check the value of STAF variable STAF/Config/CodePage. For example:

STAF testmach1 VAR RESOLVE STRING {STAF/Config/CodePage}