Redirecting JVM output

By default, output from Java applications running in a JVM is written to the HFS files that are named by the STDOUT and STDERR options in the JVM profile for the JVM. The file named by the STDOUT option is used for System.out requests, and the file named by the STDERR option is used for System.err requests. The output files are located in the working directory named by the WORK_DIR option in the JVM profile.

You can specify a fixed file name for each of the output files, in which case the output from multiple JVMs is appended to the named file, and the output is interleaved. However, the records are not given headers. Alternatively, you can use the -generate option on the STDOUT and STDERR options to specify that file names should be generated when the JVM is started up. If you do this, each JVM can have its own output files, identified by a time stamp and the applid of the CICS region. Otherwise, the output from the JVMs in all your CICS regions will be written to the same output files. However, note that the use of the -generate option is not recommended in a production environment, because it can be detrimental to the performance of your JVMs. “Options in JVM profiles” in the CICS® System Definition Guide tells you more about the STDOUT and STDERR options, and Customizing or creating JVM profiles and JVM properties files tells you how to customize the options in a JVM profile.

To gain more control over the output from your JVMs, as well as specifying the STDOUT and STDERR options, you can use the USEROUTPUTCLASS option in a JVM profile to name a Java class that intercepts the output from the JVM and messages from JVM internals. You can use this Java class to redirect the output and messages from your JVMs, and you can add time stamps and headers to the output records. The HFS files named by the STDOUT and STDERR options in the JVM profile are still used for some messages issued by the JVM, or if the class named by the USEROUTPUTCLASS option is unable to write data to its intended destination. You should therefore still specify appropriate file names for these files.

Specifying the USEROUTPUTCLASS option has a negative effect on the performance of JVMs. For best performance in a production environment, you should not use this option. However, it can be useful to specify the USEROUTPUTCLASS option during application development. This is because even if you use the -generate option on the STDOUT and STDERR options, the generated output files can only be differentiated by the applid of the CICS region and the time of generation. The USEROUTPUTCLASS option enables developers using the same CICS region to separate out their own JVM output, and direct it to an identifiable destination of their choice. The USEROUTPUTCLASS option can be used for most types of JVM, with the exception of the master JVM that initializes the shared class cache, because the output redirection class will never be invoked by the activities of the master JVM.

To use the USEROUTPUTCLASS option, specify USEROUTPUTCLASS=[java class] in a JVM profile, naming the Java class of your choice. (The class extends java.io.OutputStream.) The CICS-supplied sample JVM profiles DFHJVMPR, DFHJVMPC and DFHJVMCD contain the commented-out option USEROUTPUTCLASS=com.ibm.cics.samples.SJMergedStream, which names the CICS-supplied sample class. Uncomment this option to use the com.ibm.cics.samples.SJMergedStream class to handle output from JVMs with that profile. CICS also supplies an alternative sample Java class, com.ibm.cics.samples.SJTaskStream. The behaviour of both these classes is described later in this topic.

The classes are shipped as a middleware class file dfjoutput.jar, which is in the directory /usr/lpp/cicsts/cicsts31/lib, where cicsts31 is a user-defined value that you chose for the CICS_DIRECTORY variable used by the DFHIJVMJ job during CICS installation. The source for the classes is also provided as samples, so you can modify the classes as you want, or write your own classes based on the samples. The CICS Customization Guide tells you how to do this.

Table 1 shows what output from JVMs can and cannot be intercepted by the class named by the USEROUTPUTCLASS option. The class that you use must be able to deal with all the types of output that it might intercept.
Table 1. JVM output intercepted by Java class named by USEROUTPUTCLASS
Output type Intercepted by class
System.out output Yes
System.err output Yes
JVM internal messages Yes
Unresettable events log (controlled by ibm.jvm.events.output system property) Yes (unless another destination file is explicitly named in the system property). See note 1.
Language Environment® stdout and stderr output Not intercepted
JAVADUMP Not intercepted
HPITRACE Not intercepted
Note:
  1. The destination for information about unresettable events in a resettable JVM is controlled by the ibm.jvm.events.output system property in the JVM properties file for the JVM. If you have used that system property to name a specific HFS file as the destination for the unresettable events information, then the information goes to that file, and is not intercepted. (The default ibm.jvm.events.output system property in the CICS-supplied sample JVM properties files names the file event.log as the destination.) If the system property names the destination as stdout or stderr, then the information is intercepted by the class named on the USEROUTPUTCLASS option in the JVM profile, and directed to the destination specified by that class. If the ibm.jvm.events.output system property is null, then this output is not produced at all.

The class that you are using must be present in a directory on the trusted middleware class path used by the JVM (to which you can add paths by using the TMPREFIX or TMSUFFIX option in the JVM profile). If you are using your own class in place of the supplied sample class, any associated native code for your class must be present on the library path used by the JVM (specified by the LIBPATH option in the JVM profile), and must be explicitly loaded using the System.loadLibrary() call, either at class load time via a static initializer, or in the class constructor. (This avoids the need to include doPrivileged() blocks around the loadLibrary call when you are running with Java security active.) Note that if the JVM is to use the shared class cache (if CLASSCACHE=YES is specified in the JVM profile), you will need to include the class and any associated native code in the trusted middleware class path and library path that are specified in the JVM profile for the master JVM that initializes the shared class cache, rather than those specified in the JVM profile for the JVM itself. The CICS-supplied sample JVM profile for the master JVM is DFHJVMCC, and the JVM properties file that it references is dfjjvmcc.props.

Also bear in mind that the Java programs that will run in JVMs that use the USEROUTPUTCLASS option should include appropriate exception handling to deal with the exceptions that might be thrown by a class named on the USEROUTPUTCLASS option. The CICS-supplied sample classes handle all exceptions internally, so they do not return any errors to the calling program.