Development and Pipeline

Development and Pipeline

Development and Pipeline

Connecting mainframe application developers to discuss efficiently creating and maintaining z/OS applications

 View Only

DBB Releases New JobExec API for JCL Submission

By Jack Murray posted Tue July 25, 2023 04:27 PM

  

Introduction

In the latest version of Dependency Based Build (DBB), 2.0.1, the development team has introduced a new API to submit JCL jobs, JobExec. JobExec will replace JCLExec, DBB's existing JCL submission API. The team focused on making JobExec familiar to customers by designing an API similar to JCLExec, and on making JobExec more accessible than JCLExec by removing a dependency on SDSF.

Deprecation of JCLExec

Many users may be familiar with JCLExec, DBB's previous Job Submission API. JCLExec relied on System Display and Search Facility (SDSF) to retrieve and view the output of jobs. While SDSF can be a powerful tool, it is an extra dependency users needed to retrieve job output. For this reason, JCLExec has been deprecated and will be retired some time in the future.

Key Features and Benefits

Unlike JCLExec, JobExec does not rely on SDSF. Instead, JobExec interacts directly with the JESx spool, resulting in faster and more efficient retrieval. Both APIs submit jobs using the default life-of-job SSIB. With JobExec, users can submit JCL from a dataset, a text file on HFS, or from an inline string, and retrieve and save job output.

Getting Started

Executing JCL from a dataset:

def rc = new JobExec().dataset("USR1.JCL").member("TEST").execute()

Executing JCL from an HFS file:

def rc = new JobExec().file(new File("/u/usr1/jcl/test.jcl")).execute()

Executing JCL from an inline string:

def jcl = '''\
//HELLO  JOB ,
//       MSGCLASS=H,MSGLEVEL=(1,1),TIME=(,4),REGION=0M
//*
//* PRINT \"HELLO WORLD\" ON JOB OUTPUT
//*
//STEP0001 EXEC PGM=IEBGENER
//SYSIN    DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSUT1   DD *
HELLO, WORLD
/*
//SYSUT2   DD SYSOUT=*
//
'''

def rc = new JobExec().text(jcl).execute()

After executing, more information can be gathered about a job, including the jobID, jobName, DDNames, and job output:

def jobExec = new JobExec().dataset("USR1.JCL").member("TEST")
def rc = jobExec.execute()

def jobID = jobExec.getSubmittedJobId()
def jobName = jobExec.getSubmittedJobName()
def listDDNames = jobExec.getAllDDNames(true)

jobExec.saveOutput(new File("/u/usr1/jcl/output.txt"))

By default, saveOutput() uses the default charset reported by Java, usually an EBCDIC codepage. To save in another codepage, use saveOutput(File file, String targetEncoding). For example, saving as ASCII:

jobExec.saveOutput(new File("/u/usr1/jcl/output.txt"), "ISO8859-1")

It is also possible to save a subset of job output qualified by DD:STEP:PROC, where splat (*) can be used to retrieve all. e.g. retrieve all SYSPRINT output:

jobExec.saveOutput("SYSPRINT", new File("/u/usr1/jcl/output.txt"))

JobExec.execute() has a default wait time of 1 hour. This can be adjusted using JobExec.execute(int timeout, java.util.concurrent.TimeUnit timeUnit):

import java.util.concurrent.TimeUnit;

// Wait up to 30 minutes
jobExec.execute(30, TimeUnit.MINUTES)

// Wait up to 12 hours
jobExec.execute(12, TimeUnit.HOURS)

// Wait up to 1 day
jobExec.execute(1, TimeUnit.DAYS)

Putting it all together in a groovy script:

@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import groovy.transform.*
import com.ibm.dbb.build.*
import java.util.concurrent.TimeUnit;

def jobExec = new JobExec().dataset("USR1.JCL").member("TEST")
def rc = jobExec.execute(10, TimeUnit.MINUTES)
if (rc > 0)
    println("Job failed with return code ${rc}")

jobExec.saveOutput(new File("/u/usr1/jcl/output.txt"))

Note: Because JobExec interacts directly with the JESx spool, job output must remain on the spool long enough to gather status and output. Therefore, a job class that does not immediately archive or delete the output must be used.

Migration from JCLExec

When migrating JCLExec code to JobExec there are a few differences to be aware of:

  • JCLExec.execute() returns int 0 unless a Java exception occurred. JobExec.execute() instead returns the max return code of the JCL job.
  • By default, JCLExec did not have a maximum wait time for a job to finish. JobExec has a default wait time of one hour, which can be overridden in the execute command by JobExec.execute(int timeout, java.util.concurrent.TimeUnit timeUnit) which replaces JCLExec.executeAndWaitFor(int timeout, java.util.concurrent.TimeUnit unit)
  • JCLExec.getSubmittedJobId() returns in the form <jobName>(<jobID>) but JobExec.getSubmittedJobId() will only return <jobID>. Method JobExec.getSubmittedJobIDAsRexx() has been added to return the old form.
  • JCLExec.confDir(String confDir) was used by JCLExec to point to a configuration directory. This configuration is no longer necessary in JobExec so there are no equivalent methods to confDir(String confDir), setConfDir(String confDir), getConfDir().

Conclusion

JobExec is a powerful tool which improves upon JCLExec by offering a robust set of features for JCL submission through DBB and is more accessible than ever by requiring less dependencies. For more information, visit the JobExec documentation and Javadoc.

0 comments
65 views

Permalink