IBM®Developer Kit( 用于OS / 390,Java 2 Technology Edition,版本1.3.1和用于z / OS,版本1.4的软件开发套件(SDK))为z /上所有支持Java的子系统提供了JVM和运行时环境。操作系统,包括用于z / OS的WebSphere®Application Server , CICS® , DB2®和信息管理系统(IMS) 。 Java Developer Kit还提供了标准Java命令,可以从UNIX System Services Shell环境中运行该命令。
健壮的Java 2平台企业版(J2EE)环境(例如WebSphere Application Server for z / OS )的可用性非常重要。 但是,随着Java技术继续渗透到企业中,将Java无缝集成到现有z / OS批处理子系统和计划中的能力可能是大规模采用Java的关键。
这是z / OS批处理作业中Java的一些潜在用途:
过去,Java可能被认为是速度慢或占用大量资源,而现代JVM及其对机器代码的即时转换(JIT),在许多任务上具有出色的性能。 随着zSeries®应用程序辅助处理器(zAAP)的发布,IBM最近为在z / OS上使用Java提供了可观的财务激励。
在本文中,我们描述了在批处理作业流中使用Java时可能遇到的一些挑战,以及如何将Java无缝集成到MVS作业控制语言(JCL)中。 尽管大多数信息也适用于OS / 390,但我们将操作系统称为z / OS,只是SDK / 1.4和更高版本仅在z / OS上受支持。
在深入研究用于在z / OS批处理作业或已启动任务中运行Java的JCL之前,让我们讨论一些基本目标:
您可以使用Unix系统服务的一部分BPXBATCH实用程序来启动任何UNIX Shell命令,包括SDK内的Java Shell命令。 下面的清单1展示了一个使用BPXBATCH启动Java程序并将其输出发送到JES SYSOUT数据集的作业:
//BPXBATCH JOB (999,XXX),'JAVA BPXBATCH',CLASS=A,MSGLEVEL=(1,1)
// MSGCLASS=X,REGION=0M,NOTIFY=&SYSUID
//********************************************************************
//* Run Java under a UNIX System Service shell
//********************************************************************
//STEP2 EXEC PGM=BPXBATCH,
// PARM='SH java com.foo.MyClass arg1 arg2'
//STDIN DD DUMMY
//STDOUT DD PATH='/tmp/&SYSUID..bpxbatch.out',
// PATHOPTS=(OWRONLY,OCREAT,OTRUNC),
// PATHMODE=SIRWXU
//STDERR DD PATH='/tmp/&SYSUID..bpxbatch.err',
// PATHOPTS=(OWRONLY,OCREAT,OTRUNC),
// PATHMODE=SIRWXU
//STDENV DD *
CLASSPATH=/u/myuid/classes
//*********************************************************************
//* Copy HFS output files to SYSOUT, since BPXBATCH can only write
//* STDOUT and STDERR to HFS files.
//*********************************************************************
//STEP3 EXEC PGM=IKJEFT01,DYNAMNBR=300,COND=EVEN
//SYSTSPRT DD SYSOUT=*
//HFSOUT DD PATH='/tmp/&SYSUID..bpxbatch.out'
//HFSERR DD PATH='/tmp/&SYSUID..bpxbatcherr'
//STDOUTL DD SYSOUT=*,DCB=(RECFM=VB,LRECL=133,BLKSIZE=137)
//STDERRL DD SYSOUT=*,DCB=(RECFM=VB,LRECL=133,BLKSIZE=137)
//SYSPRINT DD SYSOUT=*
//SYSTSIN DD *
OCOPY INDD(HFSOUT) OUTDD(STDOUTL)
OCOPY INDD(HFSERR) OUTDD(STDERRL)
//
那么,BPXBATCH满足规定要求的程度如何?
您可以使用BPXBATCH实用程序BPXBATSL的特殊版本(入口点)来使Shell在相同的地址空间中生成,以解决此问题。 BPXBATSL有一个限制,除非它以root身份运行,否则它无法运行登录外壳程序,因此必须按以下步骤执行:
//STEP2 EXEC PGM=BPXBATSL,
// PARM='PGM /bin/sh -c java com.foo.MyClass arg1 arg2'
这也需要// STDENV包含所有环境变量的设置,因为/ etc / profile和.profile将不会运行。 因此,执行外壳程序脚本来处理此问题通常比直接调用Java更好。
可以使用Java本机接口(JNI)启动器接口编写自定义Java VM启动器,而不是将Java作为UNIX系统服务下的shell命令执行。 清单2演示了使用免费的JZOS Batch Launcher的JCL,它是z / OS的定制JVM启动器:
//JZOSBAT JOB (999,XXX),'JAVA JZOS',CLASS=A,MSGLEVEL=(1,1)
// MSGCLASS=X,REGION=0M,NOTIFY=&SYSUID
//JAVAJVM EXEC PGM=JZOSVM14,
// PARM='com.foo.MyClass arg1 arg2'
//STEPLIB DD DSN=JZOS.LIBRARY,DISP=SHR
//SYSPRINT DD SYSOUT=* < System stdout
//SYSOUT DD SYSOUT=* < System stderr
//STDOUT DD SYSOUT=* < Java System.out
//STDERR DD SYSOUT=* < Java System.err
//STDENV DD *
. /etc/profile
. ~/.profile
export CLASSPATH=~/myapp
for i in ~/myapp/lib/*.jar; do
export CLASSPATH=$i:$CLASSPATH
done
//
并非偶然,JZOS Batch Launcher可以更好地满足以下要求:
以下是Java应用程序中常用的环境变量:
$JAVA_HOME/bin:$JAVA_HOME/bin/classic:$JZOS_HOME
Java -help
以显示选项列表。 例如: IBM_JAVA_OPTIONS="-Xms64m -Xmx128m -Djzos.home=/u/jzos"
您可以在z / OS上使用普通的java.io包来读取和写入HFS(UNIX)文件,但不能读取和写入MVS数据集。 用于z / OS的IBM SDK Java 2 Technology Edition附带的JRIO软件包提供了处理记录的功能。 与任何IBM Java产品一样,没有源代码可用。
作为使用JRIO的替代方法,JZOS工具箱(包含JZOS ZFile类)包括:
清单3是在记录模式下读写MVS数据集的示例:
ZFile inZFile = new ZFile("//DD:INPUT", "rb,type=record,noseek");
ZFile outZFile = new ZFile("//DD:OUTPUT", "wb,type=record,noseek");
try {
byte[] recBuf = new byte[inZFile.getLrecl()];
int nRead = 0;
while((nRead = inZFile.read(recBuf)) > 0) {
outZFile.write(recBuf, 0, nRead);
}
} finally {
inZFile.close();
outZFile.close();
}
清单4是在流模式下读写MVS数据集的示例:
ZFile inZFile = new ZFile("//DD:INPUT", "rt");
ZFile outZFile = new ZFile("//DD:OUTPUT", "wt");
BufferedReader brdr;
BufferedWriter bwtr;
try {
InputStream istream = inZFile.getInputStream();
InputStreamReader rdr =
new InputStreamReader(istream, ZFile.DEFAULT_EBCDIC_CODE_PAGE);
brdr = new BufferedReader(irdr);
OutputStream ostream = outZFile.getOutputStream();
OutputStreamWriter wtr =
new OutputStreamWriter(ostream, ZFile.DEFAULT_EBCDIC_CODE_PAGE);
bwtr = new BufferedWriter(bwtr);
String line;
while ((line = brdr.readLine()) != null) {
bwtr.write(line);
bwtr.newLine();
}
} finally {
if (brdr != null) brdr.close();
if (bwtr != null) bwtr.close();
}
由于ZFile类仅在z / OS或OS / 390上运行时才可用,因此通常希望编写代码,以便在使用MVS数据集时仅使用ZFile类,而在其他情况下则使用普通的java.io类。 JZOS工具箱仅出于此目的提供FileFactory类,如下面的清单5所示。
BufferedReader brdr = FileFactory.newBufferedReader(inputFileName);
BufferedWriter bwtr = FileFactory.newBufferedWriter(outputFileName);
try {
String line;
while ((line = brdr.readLine()) != null) {
bwtr.write(line);
bwtr.newLine();
}
} finally {
if (brdr != null) brdr.close();
if (bwtr != null) bwtr.close();
}
在上面的示例中,取决于目标平台,可以在运行时配置inputFileName和outputFileName变量。 如果文件名以“ //”开头,则FileFactory类在流模式下使用ZFile,否则将使用普通的java.io类。 这样可以在工作站上开发和测试代码,然后再将其部署到大型机上。
有关更多信息,请参见JZOS ZFile类API参考 。
批处理作业通常向MVS系统控制台显示消息。 JZOS工具箱也具有此功能。
ZUtil.wto("FOO1233E processing terminated",
0x0020, // routecde
0x4000); // descriptor code
如果该消息不适合单行WTO(限制为125个字符),则会在单词边界上分解为多行WTO。
另外,有时希望使用MVS操作员命令控制批处理作业。 JZOS Batch Launcher允许批处理Java应用程序响应以下控制台命令:
有关更多信息,请参见JZOS ZUtil类API参考 。
BPXBATCH | BPXBATSL | 自定义JVM启动器(JZOS) | |
---|---|---|---|
灵活配置环境变量 | 是的,不允许变量替换和脚本编写 | 是的,不允许变量替换和脚本编写 | 是 |
将输出目录路由到SYSOUT数据集 | 没有 | 没有 | 是 |
控制输出编码与默认JVM编码分开 | 是的,使用iconv | 是的,使用iconv | 是 |
Java和非Java步骤之间的条件代码传递 | 没有 | 没有 | 是 |
使用MVS数据集和DD语句 | 没有 | 是 | 是 |
JVM在相同的地址空间中运行 | 没有 | 是 | 是 |
与MVS控制台通信 | 没有 | 是的,使用JNI例程中的_console函数 | 是 |
Java在主机上以多种形式存在-最明显的是在WebSphere中-但对于CICS,DB2和IMS等产品也发挥着重要作用。 但是,直到最近,Java在批处理环境中还是不很明显,可以说是z / OS最普遍的工作负载类型。 随着最近zAPP的发布,预计情况将会改变。
翻译自: https://www.ibm.com/developerworks/systems/library/es-java-batchz.html