JCL Explained — Beginner's Guide to Mainframe Job Control
In this tutorial, you'll learn about JCL Explained. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
JCL (Job Control Language) is the scripting language that tells an IBM Mainframe's operating system how to run a program — what inputs to use, what outputs to produce, and how much system resources to allocate for the job.
What You'll Learn
The three essential JCL statements (JOB, EXEC, DD), how to submit a COBOL program as a batch job, define datasets, use procedures, and debug common JCL errors.
Why It Matters
Without JCL, a COBOL program on a Mainframe is just code sitting on a disk. JCL is the bridge between your program and the operating system. It tells z/OS: "Run this program, read from this file, write to that file, use this much memory."
In banking, every batch job — interest calculation, statement generation, payment processing — requires JCL. Understanding JCL means you can control how enterprise batch workloads behave.
DodaZIP uses batch processing concepts inspired by JCL for its queue-based compression engine. Durga Antivirus Pro applies JCL-style job scheduling when running scheduled system scans.
Real-World Use
A bank runs a nightly batch job that processes 2 million credit card transactions. The JCL job executes a COBOL program that reads Transaction files, updates account balances, generates merchant settlement files, and produces exception reports — all in a single automated job stream with proper error handling between steps.
Learning Path
flowchart LR A["Mainframe Basics"] --> B["COBOL Programming"] B --> C["JCL Job Control
You are here"] C --> D["CICS Transactions"] D --> E["DB2 for z/OS"] style C fill:#f90,color:#fff
What Is JCL?
Think of JCL as a shipping label for your program. When you mail a package, you write:
- Who it is from (JOB statement)
- What shipping method to use (EXEC statement)
- What is inside and where it goes (DD statements)
JCL uses the same three-part structure. Every JCL job has:
- JOB statement: Names the job and sets accounting/routing information
- EXEC statement: Tells the system which program to execute
- DD (Data Definition) statements: Describe each input/output file the program needs
Analogy: JCL Is Like a Cooking Timer
Imagine you are baking a cake:
- The JOB statement says "Bake Chocolate Cake" — it names the task
- The EXEC statement says "Preheat to 350F, bake for 30 minutes" — it specifies how to run
- The DD statements list ingredients: "2 cups flour, 1 cup sugar, 3 eggs" — they define what data to use
Your First JCL Job
Here is a JCL job that runs the COBOL program PAYROLL:
//PAYJOB JOB (ACCT123),'PAYROLL RUN',CLASS=A
//STEP1 EXEC PGM=PAYROLL
//INFILE DD DSN=EMP.DATA.INPUT,DISP=SHR
//OUTFILE DD DSN=EMP.DATA.OUTPUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=SYSDA,SPACE=(TRK,(10,5))
//SYSOUT DD SYSOUT=*
//SYSIN DD *
RUN-MODE=MONTHLY
/*
The JOB Statement
//PAYJOB JOB (ACCT123),'PAYROLL RUN',CLASS=A
- //: Every JCL statement starts with
//in column 1 - PAYJOB: Job name (1-8 characters, must be unique in the system)
- JOB: Statement type — this is a job card
- (ACCT123): Accounting information (used for billing and chargeback)
- 'PAYROLL RUN': Job description (in quotes)
- CLASS=A: Job class — determines which system resources and priority to use
The EXEC Statement
//STEP1 EXEC PGM=PAYROLL
- STEP1: Step name (1-8 characters). A job can have multiple steps
- EXEC: Statement type — this tells the system to execute something
- PGM=PAYROLL: The program name to run (8 characters max on mainframes)
The DD Statements
//INFILE DD DSN=EMP.DATA.INPUT,DISP=SHR
- INFILE: DD name — how the program references this file
- DD: Statement type — Data Definition
- DSN=...: Dataset name (the Mainframe's term for a file)
- DISP=SHR: Disposition — "Share" means other jobs can read it simultaneously
//OUTFILE DD DSN=EMP.DATA.OUTPUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=SYSDA,SPACE=(TRK,(10,5))
- DISP=(NEW,CATLG,DELETE): Create a new file. If the job completes, catalog it (make it permanent). If it fails, delete it.
- UNIT=SYSDA: Store on a direct-access disk
- SPACE=(TRK,(10,5)): Allocate 10 tracks initially, 5 tracks as secondary
//SYSOUT DD SYSOUT=*
This routes program output (like COBOL's DISPLAY statements) to the job's output spool where you can read it.
//SYSIN DD *
RUN-MODE=MONTHLY
/*
Inline data. The DD * means "data follows," and /* marks the end. The program reads this as input.
Running a COBOL Program with JCL
Let's combine COBOL and JCL. Here is a complete job that compiles and runs a COBOL program:
//COBJOB JOB (COB001),'COBOL COMPILE AND RUN',CLASS=B
//COMPILE EXEC PGM=IGYCRCTL
//SYSLIB DD DSN=SYS1.COBLIB,DISP=SHR
//SYSLIN DD DSN=&&OBJECT,UNIT=SYSDA,
// DISP=(NEW,PASS),SPACE=(CYL,(1,1))
//SYSIN DD DSN=MY.COBOL.SRC(BATCHRPT),DISP=SHR
//SYSPRINT DD SYSOUT=*
//LKED EXEC PGM=IEWL,COND=(8,LT,COMPILE)
//SYSLIN DD DSN=*.COMPILE.SYSLIN,DISP=(OLD,PASS)
//SYSLMOD DD DSN=MY.LOAD(BATCHRPT),DISP=SHR
//GO EXEC PGM=BATCHRPT,COND=((8,LT,COMPILE),(8,LT,LKED))
//INFILE DD DSN=MY.DATA.INPUT,DISP=SHR
//OUTFILE DD SYSOUT=*
//SYSOUT DD SYSOUT=*
This three-step job:
- COMPILE: Runs the COBOL compiler (IGYCRCTL) to translate COBOL source into object code
- LKED: Runs the linkage editor (IEWL) to link object code into a load module
- GO: Executes the linked program
BATCHRPTwith input and output files
Notice COND=(8,LT,COMPILE) — if the compile step has a return code of 8 or higher (error), skip the link step. This prevents wasting resources on bad compiles.
Real-World Use: Monthly Statement Generation
Banks use JCL to run monthly statement generation. Here is a simplified version:
//STMTS JOB (BANK01),'MONTHLY STATEMENTS',CLASS=C
//STEP1 EXEC PGM=GENSTMT
//ACCTFILE DD DSN=BANK.ACCOUNTS.MASTER,DISP=SHR
//TXNFILE DD DSN=BANK.TRANSACTIONS.MAR,DISP=SHR
//STMTFILE DD DSN=BANK.STATEMENTS.MAROUT,
// DISP=(NEW,CATLG),UNIT=SYSDA,
// SPACE=(CYL,(50,10),RLSE)
//PRINTER DD SYSOUT=A
//ERRORLOG DD SYSOUT=*
//SYSIN DD *
REPORT-DATE=20260331
CYCLE=MONTHLY
/*
This job generates monthly statements for a bank with millions of customers, processing transactions from March and creating a new statement file.
Security Angle
JCL controls file access privileges. Using DISP=SHR allows read-only sharing. Encrypted datasets use DSNTYPE parameters. In secure environments, all JCL is audited — every file access is logged.
Durga Antivirus Pro applies similar access-control patterns when scheduling system scans, ensuring scan reports are written to secure output files that only administrators can read.
Common Errors
1. Forgetting the // prefix
PAYJOB JOB (ACCT),'TEST' -- WRONG: missing //
//PAYJOB JOB (ACCT),'TEST' -- CORRECT
2. Missing required DD statements
If a COBOL program reads a file but the JCL does not define it, the job abends with a JCL error.
3. Dataset name too long
Mainframe dataset names are limited to 44 characters (including periods between qualifiers).
4. Confusing DISP=SHR with DISP=OLD
SHR allows concurrent access; OLD gives exclusive access. Using SHR when you need to write causes data integrity issues.
5. Not checking return codes
Always use COND parameters to prevent downstream steps from running when an earlier step failed.
Practice Questions
What are the three main types of JCL statements? JOB, EXEC, and DD statements.
What does DISP=SHR mean? The dataset is shared — multiple jobs can read it at the same time.
What is the difference between a job and a step? A job is a collection of steps. Each step runs one program. Steps execute sequentially within a job.
How do you pass inline data to a JCL job? Use
DD *followed by the data lines and/*to end the data.
Challenge: Write a JCL job with three steps: compile a COBOL program, link it, and run it with input from one file and output to a new file. Include proper COND parameters to skip downstream steps if compilation fails.
Mini Project
Task: Create a JCL job for an end-of-day bank processing system.
Design a JCL job stream that:
- Step 1: Runs a COBOL program (DAYEND) that processes daily transactions
- Step 2: Runs a COBOL program (INTCALC) that calculates interest on savings accounts
- Step 3: Runs a COBOL program (GENSTMT) that generates monthly statements
- Step 4: Runs IEBGENER to archive the Transaction file to a tape dataset
Include proper DISP, SPACE, UNIT, and COND parameters. Use instream data for date parameters. Show the expected return code handling between steps.
What's Next
| Tutorial | What You'll Learn |
|---|---|
| CICS Transaction Processing | Build online Transaction programs that run alongside batch jobs |
| COBOL Explained — Beginner's Guide | Write the COBOL programs that JCL submits |
| Mainframe Explained — Complete Guide | Mainframe architecture and z/OS fundamentals |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro