编写 Java 类来重定向 JVM stdout 和 stderr 输出
在 JVM 概要文件中使用 USEROUTPUTCLASS 选项来命名用于从 JVM 拦截 stdout 流和 stderr 流的 Java™ 类。 您可以更新此类以指定您选择的时间戳记和记录头以及重定向输出。
6.3 beta 对 USEROUTPUTCLASS 函数的支持已弃用。
CICS 提供可用于此目的的样本 Java 类 com.ibm.cics.samples.SJMergedStream 和 com.ibm.cics.samples.SJTaskStream。 为 /usr/lpp/cicsts/cicsts64/samples/com.ibm.cics.samples 目录中的这两个类提供了样本源。 /usr/lpp/cicsts/cicsts64 目录是 z/OS UNIX 上 CICS 文件的安装目录。 此目录由 DFHISTAR 安装作业中的 USSDIR 参数指定。 样本类也作为类文件 com.ibm.cics.samples.jar 提供,该文件位于目录 /usr/lpp/cicsts/cicsts64/lib中。 您可以修改这些类,或者根据样本编写您自己的类。
- JVM 中由 USEROUTPUTCLASS 选项指定的类拦截的输出类型。 您使用的类必须能够处理它可能拦截的所有类型的输出。
- 提供的样本类的行为。 com.ibm.cics.samples.SJMergedStream 类为 JVM 输出和错误消息创建两个合并的日志文件,每个记录上都有一个头,其中包含 APPLID ,日期,时间,事务标识,任务号和程序名。 如果有暂态数据队列,则使用暂态数据队列创建日志文件;如果没有暂态数据队列或 Java 应用程序无法使用暂态数据队列,则使用 z/OS UNIX 文件创建日志文件。 com.ibm.cics.samples.SJTaskStream 类将单个任务的输出导向 z/OS UNIX 文件,并添加时间戳和标头,以提供特定于单个任务的输出流。
com.ibm.cics.server.outputredirectionplugin.name=class_name。 您可以使用常量 com.ibm.cics.server.Constants.CICS_USER_OUTPUT_CLASSNAME_PROPERTY 来获取属性名称。 以下代码摘录显示了如何在捆绑软件激活程序中注册服务:Properties serviceProperties = new Properties();
serviceProperties.put(Constants.CICS_USER_OUTPUT_CLASSNAME_PROPERTY, MyOwnStreamPlugin.class.getName());
context.registerService(OutputRedirectionPlugin.class.getName(), new MyOwnStreamPlugin(), serviceProperties);您可以将 OSGi 捆绑软件添加到 JVM 概要文件中的 OSGI_BUNDLES 选项,或者确保在运行第一个任务时将捆绑软件安装在框架中。 无论使用哪种方法,仍必须在 USEROUTPUTCLASS 选项中指定类。- OutputRedirectionPlugin 接口
- 输出的可能目标
- 处理输出重定向错误和内部错误
输出重定向接口
CICS 在 com.ibm.cics.server.jar中提供了一个名为 com.ibm.cics.server.OutputRedirectionPlugin 的接口,可由拦截 JVM 的 stdout 和 stderr 输出的类实现。 提供的样本实现此接口。
- 实现此接口的超类 com.ibm.cics.samples.SJStream
- 子类 com.ibm.cics.samples.SJMergedStream 和 com.ibm.cics.samples.SJTaskStream,它们是 JVM 概要文件中指定的类
与样本类一样,请确保您的类直接实现接口 OutputRedirectionPlugin ,或者扩展实现该接口的类。 您可以从超类 com.ibm.cics.samples.SJStream继承,也可以使用同一接口实现类结构。 使用任一方法,您的类都必须扩展 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
);
} 超类 com.ibm.cics.samples.SJStream 包含 com.ibm.cics.samples.SJMergedStream 和 com.ibm.cics.samples.SJTaskStream的公共组件。 它包含返回的 initRedirect() 方法false,这将有效禁用输出重定向,除非此方法被子类中的另一个方法覆盖。 它不会实现 writeRecord() 方法,此类方法必须由任何子类提供以控制输出重定向过程。 您可以在自己的类结构中使用此方法。 还可以使用构造函数而不是 initRedirect() 方法来执行输出重定向的初始化。
inPS 参数包含 JVM 的原始 System.out 打印流或原始 System.err 打印流。 您可以将日志记录写入这些底层日志记录目标中的任何一个。 不能对这些打印流中的任何一个调用 close() 方法,因为它们将永久关闭并且不可供进一步使用。
输出的可能目标
CICS提供的样本类将 JVM 的输出直接指向特定于 CICS 区域的目录; 目录名是使用与 CICS 区域关联的 APPLID 创建的。 在编写自己的类时,如果愿意,可以将多个 CICS 区域的输出发送到同一个 z/OS UNIX 目录或文件。
例如,您可能想要创建单个文件,其中包含与在多个不同 CICS 区域中运行的特定应用程序相关联的输出。
使用 Thread.start() 以编程方式启动的线程无法发出 CICS 请求。 对于这些应用程序, JVM 的输出由您为 USEROUTPUTCLASS 指定的类拦截,但无法使用 CICS 工具 (例如瞬时数据队列) 将其重定向。 您可以像提供的示例类一样,将这些应用程序的输出直接导入 z/OS UNIX 文件。
处理输出重定向错误和内部错误
如果您的类使用 CICS 设施来重定向输出,那么它们应包含相应的异常处理,以处理使用这些设施时发生的错误。
- IOErrorException
- LengthErrorException
- NoSpaceException
- NotOpenException
如果您的类直接输出到 z/OS UNIX 文件,则应包含适当的异常处理,以处理写入 z/OS UNIX 时出现的错误。 这些错误的最常见原因是安全性异常。
将在命名 USEROUTPUTCLASS 选项上的类的 JVM 中运行的 Java 程序应包含相应的异常处理,以处理类可能抛出的任何异常。 CICS提供的样本类在内部处理异常,方法是使用 "尝试/捕获" 块来捕获所有可抛出的异常,然后编写一条或多条错误消息以报告问题。 在重定向输出消息时检测到错误时,会将这些错误消息写入 System.err,使其可用于重定向。 但是,如果在重定向错误消息时发现错误,那么会将报告此问题的消息写入正在处理请求的 JVM 所使用的 JVM 概要文件中的 STDERR 选项所指示的文件。 因为样本类以这种方式捕获所有错误,这意味着调用程序不需要处理输出重定向类抛出的任何异常。 您可以使用此方法来避免对调用程序进行更改。 请注意,不要通过尝试将类发出的错误消息重定向到发生故障的目标,将输出重定向类发送到循环中。