z/os视频_z / OS和OS / 390上的Java批处理作业

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程序,该程序将数据转换为XML。
  • 使用Java程序访问API,例如SOAP / Web服务,WebSphere MQ客户端API,Java数据库连接(JDBC)数据库,自定义传输控制协议/ Internet协议(TCP / IP)套接字服务,等等。
  • 使用Java的长期运行启动任务,这些任务会定期查询数据库以查找要处理的新工作。
  • 将用COBOL编写的系统迁移到Java,以便重用Java编程技能和类库。

过去,Java可能被认为是速度慢或占用大量资源,而现代JVM及其对机器代码的即时转换(JIT),在许多任务上具有出色的性能。 随着zSeries®应用程序辅助处理器(zAAP)的发布,IBM最近为在z / OS上使用Java提供了可观的财务激励。

在本文中,我们描述了在批处理作业流中使用Java时可能遇到的一些挑战,以及如何将Java无缝集成到MVS作业控制语言(JCL)中。 尽管大多数信息也适用于OS / 390,但我们将操作系统称为z / OS,只是SDK / 1.4和更高版本仅在z / OS上受支持。

Java批处理作业要求

在深入研究用于在z / OS批处理作业或已启动任务中运行Java的JCL之前,让我们讨论一些基本目标:

灵活的环境配置
您需要一种方法来配置调用JVM所需的环境变量和参数。 与其他Java环境一样,用于z / OS的Java SDK要求在CLASSPATH环境变量中列出包含类的目录和JAR文件。 这些文件必须位于分层文件系统(HFS)或zSeries文件系统(zFS)中。 因此,Java批处理作业实际上跨越了篱笆,充分利用了UNIX系统服务。 在这种环境中设置和诊断问题可能会很痛苦,因此您将需要一些灵活性来配置CLASSPATH和其他控制JVM行为的环境变量。
输出路由
这看起来似乎不太明显,但是您希望能够将批处理作业的输出发送到普通的MVS数据集,包括JES SYSOUT数据集。 对于Java,这将包括System.out和System.err输出。 与任何作业一样,您可能希望使用系统显示和搜索工具(SDSF)之类的工具来监视作业的运行状态。
控制输出编码
您还需要控制作业输出的字符编码,因为您通常会使用ASCII作为默认编码来运行JVM。 为了理解此要求,我们首先需要对Java编码进行一些解释:在内部,Java始终运行以Unicode编码的字符,但是file.encoding系统属性指定了在将Java字符与其他字符进行相互转换时使用的字符集。用于输入和输出的字节。 在z / OS上, LANG环境变量确定缺省编码,通常为IBM-1047 (EBCDIC)。 但是,某些Java应用程序错误地认为默认编码是ASCII代码页,例如ISO-8859-1 。 为了使这些应用程序正常运行,必须将file.encoding属性设置为ISO-8859-1。 如果无法单独控制Java系统输出的编码,则系统输出也将以ASCII形式编写。 因此,您将需要一种与默认JVM编码分开控制作业输出编码的方法。
条件代码传递
如果Java作业步骤可以与同一作业中的其他程序和实用程序很好地配合,那就太好了。 具体来说,您想使用Java System.exit()方法来终止Java程序,并将退出代码作为条件代码从作业步骤中传递出去。
使用MVS数据集和DD语句
标准的java.io软件包仅适用于HFS或zFS文件,但是能够通过名称或在JCL中使用DD卡来使用传统的MVS数据集将是很好的选择。 具有此功能使您可以在作业的Java和非Java步骤之间创建和传递临时数据集。
在相同的地址空间中执行JVM
对于z / OS UNIX系统服务的新用户来说,发现每个新的UNIX进程可以创建一个单独的OMVS地址空间常常令人感到惊讶。 这种行为通常会在传统的MVS批处理环境中引起问题。 首先,地址空间不共享DD名称,SYSOUT文件和其他数据集分配。 如果将JVM启动到单独的地址空间中,则此处提出的目标可能变得难以实现。 此外,如果使用多个地址空间,则作业监视和性能管理可能会很棘手。 将为每个地址空间创建诸如服务管理框架(SMF)类型30记录之类的记帐数据,这通常是不希望的。
与MVS作业日志和系统控制台进行通信
批处理作业通常使用写操作员(WTO)宏将消息写入作业日志和系统控制台。 对于长时间运行的作业和开始的任务,系统操作员可能希望使用MVS STOP(P)命令正常停止程序,或者使用MODIFY(F)命令向其发送任意命令。

使用BPXBATCH运行Java批处理作业

您可以使用Unix系统服务的一部分BPXBATCH实用程序来启动任何UNIX Shell命令,包括SDK内的Java Shell命令。 下面的清单1展示了一个使用BPXBATCH启动Java程序并将其输出发送到JES SYSOUT数据集的作业:

清单1.使用BPXBATCH运行Java批处理作业
//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满足规定要求的程度如何?

  • 灵活的环境配置 :可以在用户的​​默认.profile登录脚本中或通过使用// STDENV DD指定环境变量,例如CLASSPATH。 但是// STDENV数据集不允许进行变量替换或任何形式的脚本编写。 有关更多信息,请参见Java使用的环境变量 。
  • 输出路由 :将Java System.out和System.err流发送到// STDOUT和// STDERR。 BPXBATCH仅支持这些DD的HFS文件,因此需要一个单独的步骤将这些文件复制到SYSOUT数据集。 这也意味着您无法在作业完成之前查看输出。
  • 控制输出编码 :不能与默认的file.encoding系统属性分开控制默认的输出编码,因此需要单独的步骤进行转换。
  • 条件代码传递 :您不能使用System.exit()将Java条件代码传递到后续步骤。
  • MVS数据集和DD语句的使用 :Java记录IO(JRIO)软件包(包括在Java开发人员平台的Java开发工具包中)允许进行记录I / O访问。 尽管最初仅支持EBCDIC代码页,但是从2003年第四季度开始,JRIO支持z / OS支持的所有代码页。 JRIO支持转换dsname和路径名,但是不会转换客户数据(包括密钥)。 为了使用作业步骤DD语句,必须在相同的地址空间中启动JVM(请参见下文)。 (有关更多信息,请参见读取和写入MVS数据集 。)
  • 在相同的地址空间中执行JVM :默认情况下,BPXBATCH在单独的地址空间中启动Java JVM,这样Java程序就无法在作业步骤中访问DD数据集分配。

    您可以使用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更好。

  • 与作业日志和系统控制台进行通信 :BPXBATCH或Java SDK中不存在写入WTO消息或响应操作员STOP或MODIFY命令的功能。 Java程序可以对C程序进行JNI调用,然后可以调用_console或_console2 C函数来发出WTO或与STOP和MODIFY交互。 有关更多信息,请参见与MVS系统控制台通信 。

使用自定义JVM启动器运行Java批处理作业

可以使用Java本机接口(JNI)启动器接口编写自定义Java VM启动器,而不是将Java作为UNIX系统服务下的shell命令执行。 清单2演示了使用免费的JZOS Batch Launcher的JCL,它是z / OS的定制JVM启动器:

清单2.使用定制的JVM启动器运行Java批处理作业
//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可以更好地满足以下要求:

  • 灵活的环境配置 :// STDENV文件指向UNIX shell脚本,该脚本导出要设置的所有环境变量。 运行外壳程序脚本的能力本身可能会调用其他程序或外壳程序脚本,它允许在配置环境时提供灵活性和重用性。 在上面的示例中,添加到lib目录中的新JAR将自动添加到CLASSPATH中。
    注意:根据设计,JZOS Batch Launcher不会自动运行登录外壳程序,因此,如果要运行/ etc / profile和用户的登录配置文件,则必须明确执行它们。 有关更多信息,请参见Java使用的环境变量 。
  • 输出路由 :STDOUT和STDERR文件可能直接路由到JES SYSOUT数据集(或MVS数据集)。 您可以在作业运行时监视输出。
  • 控制输出编码 :无论默认的file.encoding系统属性如何,输出编码默认为环境变量“ LANG”所隐含的代码页。 如果定义了JZOS_OUTPUT_ENCODING环境变量,则其值将用于更改默认输出编码。
  • 条件代码传递 :Java条件代码从System.exit()传递到后续步骤。
  • MVS数据集和DD语句的使用 :JZOS ZFile类为标准C库I / O例程提供了灵活的JNI包装器。 有关更多信息,请参见读取和写入MVS数据集 。
  • 在相同的地址空间中执行JVM :JZOS VM启动器在原始地址空间下调用JVM,以便Java程序在作业步骤中确实可以访问DD数据集分配。 由于未使用辅助地址空间,因此Java程序在原始WLM组下运行。
  • 与作业日志和系统控制台进行通信 :ZOS ZUtil类提供了用于编写控制台消息和响应操作员命令的方法。 有关更多信息,请参见与MVS系统控制台通信 。

Java使用的环境变量

以下是Java应用程序中常用的环境变量:

  • PATH :目录列表,以冒号(“:”)分隔,用于查找可执行二进制文件。 这应该包括$ JAVA_HOME / bin。
  • LIBPATH :目录列表,以冒号分隔,用于查找共享库。 这应该包括应用程序使用的任何JNI库所需的所有库。 运行JZOS启动器时,必须包括:
    $JAVA_HOME/bin:$JAVA_HOME/bin/classic:$JZOS_HOME
  • JZOS Batch Launcher CLASSPATH :目录和JAR / ZIP文件的列表,以冒号分隔,从中加载Java类。 这应该包括Java应用程序使用的目录或单个JAR文件。 运行JZOS Batch Launcher时,还必须包括$ JZOS_HOME / jzos.jar。
  • IBM_JAVA_OPTIONS :JVM的选项的空格分隔列表。 在z / OS或OMVS shell中键入Java -help以显示选项列表。 例如:
    IBM_JAVA_OPTIONS="-Xms64m -Xmx128m -Djzos.home=/u/jzos"

从Java读取和写入MVS数据集

您可以在z / OS上使用普通的java.io包来读取和写入HFS(UNIX)文件,但不能读取和写入MVS数据集。 用于z / OS的IBM SDK Java 2 Technology Edition附带的JRIO软件包提供了处理记录的功能。 与任何IBM Java产品一样,没有源代码可用。

作为使用JRIO的替代方法,JZOS工具箱(包含JZOS ZFile类)包括:

  • z / OS C文件IO API(fopen,fclose,fread,fwrite等)的JNI包装器。
  • 支持C库提供的所有IO模型(“记录”和“流”模式)。 有关更多信息,请参见《 z / OS C / C ++编程指南》 。
  • Java源代码。

清单3是在记录模式下读写MVS数据集的示例:

清单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数据集的示例:

清单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所示。

清单5. FileFactory类
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系统控制台进行通信

批处理作业通常向MVS系统控制台显示消息。 JZOS工具箱也具有此功能。

ZUtil.wto("FOO1233E processing terminated", 
              0x0020,   // routecde
              0x4000);  // descriptor code

如果该消息不适合单行WTO(限制为125个字符),则会在单词边界上分解为多行WTO。

另外,有时希望使用MVS操作员命令控制批处理作业。 JZOS Batch Launcher允许批处理Java应用程序响应以下控制台命令:

  • START :如果Java作业作为MVS启动的任务运行,则它可能会访问此命令上指定的选项。
  • STOP(P) :此命令使JZOS Batch Launcher发出Java System.exit(),该Java System.exit()调用任何Java关闭钩子并终止JVM。
  • MODIFY(F) :JZOS Batch Launcher允许Java应用程序注册一个钩子以拦截MVS MODIFY命令。

有关更多信息,请参见JZOS ZUtil类API参考 。

简介:启动批处理Java作业的工具比较

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

你可能感兴趣的:(大数据,数据库,python,linux,java)