Skip to content

How do you map JCL job dependencies and dataset lineage?

The short answer

Read every job's steps and DD statements to see which program each step runs and which datasets it reads and writes, after resolving procedures and symbolic parameters. Then connect jobs through the datasets they share: a dataset one job writes and another reads is a dependency between them. Linking each program's files to the DD names that bind them lets you follow data from the program that writes it, through the dataset, to every job downstream.

By Nisius · Updated

What does JCL tell you, and what does it hide?

JCL tells you a great deal: which program or procedure each step executes, which datasets each DD statement binds and with what disposition, which steps run only when an earlier step ended cleanly, and which temporary datasets are passed from step to step.

It hides some things too. Symbolic parameters such as &ENV change dataset names from one environment to another. Procedures move the real steps into another member. The order in which jobs run is usually held in a scheduler, not in the JCL. And a program can choose which program to call at run time, which no reading of the JCL can settle.

How do you build the map step by step?

  • Collect the JCL, the procedure libraries it references, and the programs it executes.
  • Expand procedures and substitute symbolic parameters, so every DD statement resolves to a real dataset name for the environment you care about.
  • For each step, record the program it executes and every dataset it reads or writes, with the line each fact came from.
  • Inside each program, link its file definitions to the DD names, so a program's READ or WRITE becomes a read or write of a named dataset.
  • Connect jobs through datasets: when one job writes a dataset and another reads it, record that the first feeds the second.
  • List what did not resolve, such as a dataset nobody writes or a call decided at run time, and add what only people know, such as the schedule, from your operations team.

What are the common pitfalls?

  • Matching dataset names before symbolic parameters are substituted, which splits one dataset into several or merges different ones.
  • Ignoring temporary datasets passed between steps, which hides how a job works inside.
  • Treating generation data groups as unrelated datasets.
  • Reading conditional steps as if they always run.
  • Drawing a dependency you inferred but cannot point to in the source. Mark it as a guess or leave it out.

How Telikos does it

Telikos parses JCL and procedures alongside the COBOL and DB2 SQL they run, and its resolver links a JCL step to the program it executes, a program's file to the dataset its job binds, and a dataset one job writes to the jobs that read it. Every link carries its source locations and a confidence.

Links it cannot prove are recorded as unknowns, and your experts can add the ones the code cannot show, such as a schedule or a manual step.

How it works, in detail →

Related questions

Can job scheduling order be recovered from JCL alone?

Usually not. JCL shows what each job reads and writes, which reveals data dependencies, but the run order is normally defined in a scheduler. Combine the data dependencies from the JCL with the schedule from your operations team.

What is dataset lineage on a mainframe?

It is the path data takes through the batch estate: which program writes a dataset, which jobs read it, and which datasets and tables those jobs produce in turn. It is assembled from JCL DD statements, the programs' file definitions and their SQL.

Read next

See it on your own code

A pilot runs this on one flow you choose, inside your network, in three weeks.