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 stream and stderr stream from the JVM. You
can update this class to specify your choice of time stamps and record headers, and to redirect the
output.
6.3 beta Support for USEROUTPUTCLASS function is deprecated.
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 /usr/lpp/cicsts/cicsts64/samples/com.ibm.cics.samples directory. The /usr/lpp/cicsts/cicsts64 directory is the
installation directory for CICS files on z/OS
UNIX . This
directory is specified by the USSDIR parameter in the DFHISTAR installation
job. The sample classes are also shipped as a class file, com.ibm.cics.samples.jar
, which is in the directory /usr/lpp/cicsts/cicsts64/lib. You can modify these
classes, or write your own classes based on the samples.
- The types of output from JVMs that are and are not intercepted by the class that is 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.
- The behavior of the supplied sample classes. The com.ibm.cics.samples.SJMergedStream class creates two merged log files for JVM output and for error messages, with a header on each record that contains APPLID, date, time, transaction ID, task number, and program name. The log files are created by using transient data queues, if they are available; or z/OS UNIX files, if the transient data queues are not available, or cannot be used by the Java application. The com.ibm.cics.samples.SJTaskStream class directs the output from a single task to z/OS UNIX files, adding time stamps and headers, to provide output streams that are specific to a single task.
com.ibm.cics.server.outputredirectionplugin.name=class_name. You can use
the constant com.ibm.cics.server.Constants.CICS_USER_OUTPUT_CLASSNAME_PROPERTY to
get the property name. The following code excerpt shows how you might register your service in the
bundle activator:
Properties serviceProperties = new Properties();
serviceProperties.put(Constants.CICS_USER_OUTPUT_CLASSNAME_PROPERTY, MyOwnStreamPlugin.class.getName());
context.registerService(OutputRedirectionPlugin.class.getName(), new MyOwnStreamPlugin(), serviceProperties);
You can either add the OSGi bundle to the OSGI_BUNDLES option in the JVM profile,
or ensure that the bundle is installed in the framework when the first task is run. Whichever method
you use, you must still specify the class in the USEROUTPUTCLASS option.- The OutputRedirectionPlugin interface
- Possible destinations for output
- Handling output redirection errors and internal errors
The output redirection interface
CICS supplies an interface called com.ibm.cics.server.OutputRedirectionPlugin in com.ibm.cics.server.jar, which can be implemented by classes that intercept the stdout and stderr output from the JVM. The supplied samples implement this interface.
- A superclass com.ibm.cics.samples.SJStream that implements this interface
- The subclasses com.ibm.cics.samples.SJMergedStream and com.ibm.cics.samples.SJTaskStream, which are the classes named in the JVM profile
Like the sample classes, ensure that your class implements the interface OutputRedirectionPlugin directly, or extends a class that implements the interface. You can either inherit from the superclass com.ibm.cics.samples.SJStream, or implement a class structure with the same interface. Using either method, your class must extend java.io.OutputStream.
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 another method 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 can use this method in your own class structure. The initialization of output redirection can also be performed using a constructor, rather than the initRedirect() method.
The inPS parameter contains either the original System.out print stream or the original System.err print stream of the JVM. You can write logging to either of these underlying logging destinations. You must not call the close() method on either of these print streams because they remain closed permanently and are not available for further use.
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 z/OS UNIX 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.
Threads that are started programmatically using Thread.start() 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 z/OS UNIX files, as the supplied sample classes do.
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.
- IOErrorException
- LengthErrorException
- NoSpaceException
- NotOpenException
If your classes direct output to z/OS UNIX files, they should include appropriate exception handling to deal with errors that occur when writing to z/OS UNIX. 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.