MainframeMaster

MODS Programming

MODS programming is the practice of using the MODS control statement to plug your own exit routines into a DFSORT step and of structuring your JCL and code so that the step finds and runs those exits correctly. This includes choosing MODS syntax (one module vs separate modules for E15 and E35), ensuring the load library is available via STEPLIB or JOBLIB, and understanding how your exits interact with INREC, OUTREC, and other control statements. This page focuses on programming practices: MODS syntax options, using E15 and E35 together, JCL setup, and when to prefer exits vs built-in reformatting.

Other DFSORT Topics
Progress0 of 0 lessons

MODS Syntax Options

The MODS statement tells DFSORT which load module(s) contain your exit code. Exact syntax depends on your DFSORT (or SyncSort) product and release. Common forms include: a single module name (e.g. MODS=(MYEXIT)), which may be used for a default exit type or when one module contains multiple exit entry points; and the form that assigns modules by exit type (e.g. MODS=(E15=MYE15,E35=MYE35)), which explicitly ties each exit to a load module. If you use one module for both E15 and E35, the product may expect specific entry point names or a single entry that handles both; check the product manual. Prefer the E15= and E35= form when you have separate modules so it is clear which program runs at input and which at output.

One Module vs Multiple Modules

You can put the E15 and E35 logic in a single load module (with two entry points, if the product supports it) or in two (or more) separate modules. Using separate modules has advantages: you can change or fix the E15 without relinking the E35, you can test one exit in isolation, and you can reuse the same E15 or E35 in different jobs. A single module can be simpler to deploy (one member to copy) but ties the two exits together. Choose based on how your site manages load libraries and how often you expect to change each exit.

JCL: STEPLIB and JOBLIB

DFSORT loads the module(s) named in MODS from the step’s library concatenation. That is usually the STEPLIB DD statement for the sort step—for example, a PDS or PDSE containing your exit load modules. If you put STEPLIB on the JOB statement (as JOBLIB), all steps in the job can use it. The system searches the concatenation in order; the first matching member name is loaded. So ensure the dataset that contains your exit is in STEPLIB (or JOBLIB) and that the member name matches exactly what you coded in MODS. Case and length matter: MODS=(MYE15) looks for a member named MYE15.

Example JCL and SYSIN

A typical pattern is: a STEPLIB DD that points to your load library, SORTIN and SORTOUT (and optionally SORTWKnn for sort work), and SYSIN with your control statements including MODS. The following is a simplified example; adjust dataset names and MODS syntax to your product.

text
1
2
3
4
5
6
7
8
9
//SORTSTEP EXEC PGM=SORT //STEPLIB DD DSN=MY.USER.LOAD,DISP=SHR //SORTIN DD DSN=MY.INPUT,DISP=SHR //SORTOUT DD DSN=MY.OUTPUT,DISP=(NEW,CATLG),... //SYSIN DD * MODS=(E15=MYE15,E35=MYE35) SORT FIELDS=(1,10,CH,A) OPTION COPY /*

Here, STEPLIB tells the step where to find MYE15 and MYE35. MODS names both modules; OPTION COPY is often used during testing so only the exit and copy logic run. Replace OPTION COPY with a real sort when you are done testing.

Using E15 and E35 Together

In the same step you can specify both an E15 and an E35. E15 runs during the input phase: each time a record is read, DFSORT calls your E15 so you can pass, modify, drop, or expand it. E35 runs during the output phase: each time a record is about to be written, DFSORT calls your E35 so you can modify or drop it. So you can do input-side logic (e.g. parse and filter) in E15 and output-side logic (e.g. format or suppress) in E35. They do not share storage unless you arrange it (e.g. via a common table or dataset); each is called independently with its own parameter list.

Interaction with INREC, OUTREC, and Other Statements

You can use MODS in the same step as INREC, OUTREC, INCLUDE, OMIT, OUTFIL, and other control statements. The order in which DFSORT applies them is defined by the product: for example, E15 might run before or after INREC and INCLUDE/OMIT, and E35 might run before or after OUTREC. The DFSORT Application Programming Guide (or equivalent for your product) describes the exact processing order. In general, E15 is on the input side and E35 on the output side, so your exit and the built-in reformatting can both affect the data at different stages. Design your exit assuming it will see the record in the format present at that stage; if INREC has already reformatted the record before E15 runs, your exit sees the reformatted record.

When to Use MODS vs INREC/OUTREC

Use INREC and OUTREC when they can do the job: they are easier to change (no compile/link), and they are self-documenting in SYSIN. Use MODS and user exits when you need logic that cannot be expressed with built-in operators—variable-length parsing, one-to-many record creation, calls to other programs or tables, or complex stateful logic. Once you introduce MODS, you also need to manage load libraries and the exit interface; use it when the requirement justifies that extra complexity.

Load Failures and Name Mismatches

If the step fails with a load error (e.g. "program not found" or an abend indicating the module could not be loaded), the usual cause is that the module is not in the library concatenation or the name in MODS does not match the member name. Check that STEPLIB (or JOBLIB) includes the dataset that contains the member, that the member name matches MODS exactly (including length and case if applicable), and that the dataset is not empty or corrupted. If you use multiple libraries in the concatenation, ensure the correct one is first if the same member name could exist in more than one library.

Explain It Like I'm Five

MODS programming is like telling the sorting machine: "When you work, call these two helpers by name—one when you read a card (E15) and one when you write a card (E35)." You have to put the helpers in a box (the load library) that the machine can open (STEPLIB), and you have to use the exact names (MODS syntax) so the machine knows who to call. If the names or the box are wrong, the machine says "I can't find your helper" and stops.

Exercises

  1. What is the purpose of STEPLIB in a job that uses MODS?
  2. Give one advantage of using separate load modules for E15 and E35.
  3. Can you use MODS and INREC in the same step? What should you check in the manual?
  4. Your job fails with "program not found" after you added MODS=(MYEXIT). What do you check first?

Quiz

Test Your Knowledge

1. Can you use both an E15 and an E35 exit in the same DFSORT step?

  • No, only one exit is allowed
  • Yes; you can specify both in MODS (e.g. MODS=(E15=name1,E35=name2)) so input and output are both processed by your code
  • Only with MERGE
  • Only with OPTION COPY

2. Why would you put E15 and E35 in separate load modules?

  • DFSORT requires it
  • Separate modules let you change one exit without relinking the other and can make testing and reuse easier
  • It is faster
  • Only E15 can be in a separate module

3. What is the purpose of STEPLIB in a job that uses MODS?

  • It defines SORTIN
  • It tells the system where to find the load module(s) named in MODS so DFSORT can load your exit(s)
  • It is only for COBOL
  • STEPLIB is not used with MODS

4. How does MODS interact with INREC and OUTREC?

  • MODS replaces INREC and OUTREC
  • Both can be used; the exit runs at its defined phase (e.g. E15 before or in conjunction with input processing, E35 before output). Order is defined by the product; check the Application Programming Guide
  • INREC and OUTREC disable the exit
  • Only one of MODS or INREC can be used

5. What should you do if the job fails with "program not found" when using MODS?

  • Remove MODS
  • Verify the load module name in MODS matches the member name in the library, and that the library is in STEPLIB or JOBLIB for the step
  • Use INCLUDE instead
  • Change the sort key