Writing Java classes to redirect JVM stdout and stderr output

Use the USEROUTPUTCLASS option in a JVM profile to name a Java™ class that intercepts the stdout and stderr output from the JVM. You can tailor this class to specify your choice of time stamps and record headers, and to redirect the output.

CICS® supplies sample Java classes, com.ibm.cics.samples.SJMergedStream and com.ibm.cics.samples.SJTaskStream, that you can use for this purpose. Sample source is provided for both these classes, in the directory /usr/lpp/cicsts/cicsts31/samples/useroutputclass, where cicsts31 is a user-defined value that you chose for the CICS_DIRECTORY variable used by the DFHIJVMJ job during CICS installation. They are also shipped as a middleware class file, dfjoutput.jar, which is in the directory /usr/lpp/cicsts/cicsts31/lib. You can modify these classes, or write your own classes based on the samples.

Java Applications in CICS has information about:

For a JVM to use an output redirection class that you have modified or written, the class 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). When you are using your own class in place of a CICS-supplied sample class, any associated native code for your class must be present on the library path used by the JVM, 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.

Because the output redirection classes are placed on the trusted middleware class path, they should be coded to the standards required of trusted middleware code. Middleware is responsible for resetting itself correctly at the end of a transaction and, if necessary, for reinitializing at the beginning of a new transaction, in order to isolate different applications from each other. Persistent Reusable Java Virtual Machine User's Guide explains how middleware should be written.

If you decide to write your own classes, you need to know about:

These considerations are described below.

The com.ibm.cics.server.OutputRedirectionPlugin interface

CICS supplies an interface called com.ibm.cics.server.OutputRedirectionPlugin, shipped in dfjcics.jar, which can be implemented by classes that intercept the stdout and stderr output from the JVM. The CICS-supplied samples implement this interface. The sample classes themselves are made up of:

It is recommended that, like the sample classes, your class implements the interface OutputRedirectionPlugin directly, or extends a class which itself implements the interface. You can achieve this either by inheriting from the superclass com.ibm.cics.samples.SJStream, or by implementing a class structure with the same interface. Whether or not your class implements the interface OutputRedirectionPlugin, it must extend java.io.OutputStream.

The initRedirect() method receives a set of parameters, which are used by the output redirection class or classes. The coding for the interface is as follows:

package com.ibm.cics.server;

import java.io.*;

public interface OutputRedirectionPlugin {

  public boolean initRedirect( String inDest,
                            PrintStream inPS,
                            String inApplid,
                            String inProgramName,
                            Integer inTaskNumber,
                            String inTransid
                           );
  }               

The superclass com.ibm.cics.samples.SJStream contains the common components of com.ibm.cics.samples.SJMergedStream and com.ibm.cics.samples.SJTaskStream. It contains an initRedirect method that returns ‘false’, which effectively disables output redirection unless this method is overridden by one provided in a subclass. It does not implement a writeRecord method, and such a method must be provided by any subclass to control the output redirection process.You could imitate this in your own class structure. The initialization of output redirection can also be performed using a constructor, rather than the initRedirect method.

Note:
Start of change
Your output redirection class should not call the close() method of the original PrintStream passed on the initRedirect() method call, even when the close() method of the output redirection class is called. If the original PrintStream is closed, it will not be available for further use, either during the execution of the current program, or in subsequent reuses of the same JVM.
End of change

Possible destinations for output

The CICS-supplied sample classes direct output from JVMs to a directory that is specific to a CICS region. (The directory name is created using the applid associated with the CICS region.) When you write your own classes, if you prefer, you can send output from several CICS regions to the same HFS directory or file. For example, you might want to create a single file containing the output associated with a particular application that runs in several different CICS regions.

Java applications executing on threads other than the initial process thread (IPT) are not able to make CICS requests. For these applications, the output from the JVM is intercepted by the class you have specified for USEROUTPUTCLASS, but it cannot be redirected using CICS facilities (such as transient data queues). You can direct output from these applications to HFS files, as the supplied sample classes do. For Java applications that are executing on the IPT, you can use CICS facilities, such as transient data queues, to redirect the output.

Handling output redirection errors and internal errors

If your classes use CICS facilities to redirect output, they should include appropriate exception handling to deal with errors in using these facilities. For example, if you are writing to the transient data queues CSJO and CSJE, and using the CICS-supplied definitions for these queues, the following exceptions might be thrown by TDQ.writeData:

If your classes direct output to HFS files, they should include appropriate exception handling to deal with errors that occur when writing to HFS. The most common cause of these errors is a security exception.

The Java programs that will run in JVMs that name your classes on the USEROUTPUTCLASS options should include appropriate exception handling to deal with any exceptions that might be thrown by your classes. The CICS-supplied sample classes handle exceptions internally, by using a Try/Catch block to catch all throwable exceptions, and then writing one or more error messages to report the problem. When an error is detected while redirecting an output message, these error messages are written to System.err, making them available for redirection. However, if an error is found while redirecting an error message, then the messages which report this problem are written to the file indicated by the STDERR option in the JVM profile used by the JVM that is servicing the request. Because the sample classes trap all errors in this way, this means that the calling programs do not need to handle any exceptions thrown by the output redirection class. You can use this method to avoid making changes to your calling programs. Be careful that you do not send the output redirection class into a loop by attempting to redirect the error message issued by the class to the destination which has failed.

Related tasks
Redirecting JVM output
Using DFHJVMRO to modify the Language Environment enclave for a JVM
Using DFHJVMAT to modify options in a JVM profile
Rewriting user-replaceable programs
Assembling and link-editing user-replaceable programs
[[ Contents Previous Page | Next Page Index ]]