JCL (Job Control Language): Complete Beginner's Guide
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, and DD
- How to submit a COBOL program as a batch job
- How to define input files, output files, and temporary datasets
- How to read JCL error messages and debug common mistakes
Why JCL 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.
Learning Path
flowchart LR
A[Mainframe Basics] --> B[COBOL Programming]
B --> C[JCL Job Control<br/>You are here]
C --> D[CICS Transactions]
D --> E[DB2 & IMS Databases]
What Is JCL?
Think of JCL as a shipping label for your program. When you mail a package, you write:
- Who it’s from (JOB statement)
- What shipping method to use (EXEC statement)
- What’s 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’re baking a cake:
- The JOB statement says “Bake Chocolate Cake” — it names the task
- The EXEC statement says “Preheat to 350°F, 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’s 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
/*Let’s break down every line:
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/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’s 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’s 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 Mistakes
1. Forgetting the // prefix
PAYJOB JOB (ACCT),'TEST' <- WRONG: missing //
//PAYJOB JOB (ACCT),'TEST' <- CORRECT2. Missing required DD statements
If a COBOL program reads a file but the JCL doesn’t 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=SHRmean? 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.What does
COND=(8,LT,COMPILE)do? It tells the system: skip this step if the COMPILE step’s return code is 8 or higher (error).
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.
FAQ
Try It Yourself
Since most people don’t have access to a mainframe, you can simulate JCL concepts with Bash:
#!/bin/bash
# JOB PAYJOB
echo "=== JOB PAYJOB STARTED ==="
# EXEC PGM=PAYROLL
echo "Step: PAYROLL Processing"
# DD INFILE
echo "Reading: EMP.DATA.INPUT"
# Process data
while IFS= read -r line; do
echo "Processing: $line"
done < /dev/stdin # like DD *
# DD OUTFILE
echo "Writing: EMP.DATA.OUTPUT"
echo "=== JOB PAYJOB COMPLETED ==="Run it:
echo -e "EMP001,50000\nEMP002,75000" | ./simulate_jcl.shExpected output:
=== JOB PAYJOB STARTED ===
Step: PAYROLL Processing
Reading: EMP.DATA.INPUT
Processing: EMP001,50000
Processing: EMP002,75000
Writing: EMP.DATA.OUTPUT
=== JOB PAYJOB COMPLETED ===What’s Next
| Tutorial | What You’ll Learn |
|---|---|
| Mainframe Explained — Complete Guide | Mainframe architecture and z/OS fundamentals |
| COBOL Programming | Write the COBOL programs that JCL submits |
| Python Scripting for Automation | Compare JCL batch scripting with Python automation |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-06.
What’s Next
Congratulations on completing this Jcl tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro