MainframeMaster

JCL Tutorial

JCL Include (JCLLIB)

Building modular JCL with external code fragments and library management

Progress0 of 0 lessons

What is JCL Include?

JCL Include is a mechanism that allows you to insert predefined JCL code fragments from libraries into your job stream. This promotes modular JCL development by enabling reuse of common code patterns across multiple jobs without duplication.

Key benefits of using JCL Include:

  • Reduced code duplication through reuse of common JCL fragments
  • Improved maintainability by centralizing code that appears in multiple jobs
  • Enhanced standardization across the organization
  • Simplified job streams by abstracting complex JCL into managed components
  • More flexible than cataloged procedures for certain use cases

JCLLIB Statement

The JCLLIB statement specifies the libraries that contain procedures and include members for a job. It establishes the search order for these libraries.

JCLLIB Syntax

jcl
1
2
//jobname JOB parameters // JCLLIB ORDER=(library1,library2,...)

The JCLLIB statement must appear after the JOB statement but before any EXEC statements that reference procedures or INCLUDE statements.

When the system searches for a procedure or include member, it searches the libraries in the order specified in the JCLLIB statement, and then the standard system procedure libraries.

Example JCLLIB Usage

jcl
1
2
3
4
5
6
7
8
9
10
//MYJOB JOB (ACCT),'MY JOB',CLASS=A //*-------------------------------------------------- //* Specify procedure and include libraries //*-------------------------------------------------- // JCLLIB ORDER=(USER.PROCLIB, // DEPT.PROCLIB, // SYS1.USERPROC) //STEP1 EXEC MYPROC //STEP2 EXEC PGM=MYPROG //...

In this example, when the system looks for the procedure MYPROC, it will search the libraries in this order:

  1. USER.PROCLIB
  2. DEPT.PROCLIB
  3. SYS1.USERPROC
  4. Standard system procedure libraries (like SYS1.PROCLIB)

INCLUDE Statement

The INCLUDE statement inserts JCL code from a specified library member directly into the job stream at the point where the INCLUDE appears.

INCLUDE Syntax

jcl
1
// INCLUDE MEMBER=membername

The system searches for the member in the libraries specified in the JCLLIB statement, or in the standard system include libraries if no JCLLIB statement is present.

Example Include Usage

jcl
1
2
3
4
5
6
7
8
9
10
11
//MYJOB JOB (ACCT),'MY JOB',CLASS=A // JCLLIB ORDER=(USER.JCLLIB) //*-------------------------------------------------- //* Include standard JCL fragment for DB2 setup //*-------------------------------------------------- // INCLUDE MEMBER=DB2SETUP //*-------------------------------------------------- //* The rest of the job //*-------------------------------------------------- //STEP1 EXEC PGM=DB2PROG //...

In this example, the contents of the DB2SETUP member from USER.JCLLIB will be inserted at the point of the INCLUDE statement, as if it had been coded directly in the job.

Important: The included JCL is inserted during the conversion phase, before execution. All JCL rules and syntax must be valid after the inclusion.

Creating Include Members

Include members are created and stored as members of a partitioned dataset (PDS or PDSE). They can contain any valid JCL statements that would normally appear in a job.

Include Member Content Example

Here's an example of what might be in the DB2SETUP include member:

jcl
1
2
3
4
5
6
7
8
//*-------------------------------------------------- //* Standard DB2 environment setup //*-------------------------------------------------- //DB2LIB DD DSN=SYS1.DB2.LOADLIB,DISP=SHR //DBRMLIB DD DSN=USER.DB2.DBRMLIB,DISP=SHR //SYSTSIN DD * DSN SYSTEM(DB01) /*

When this member is included in a job, these statements will be inserted exactly as they appear here.

Include Member Design Considerations

  • Include members should be self-contained and focused on a specific function
  • They should be designed to work in multiple contexts
  • Consider using symbolic parameters for flexibility
  • Document dependencies and assumptions clearly with comments
  • Avoid hardcoding values that might need to change across environments

Managing JCL Libraries

Effective management of JCL libraries is crucial for a successful modular JCL implementation:

Library Organization

Organize libraries by function, department, or application area to make members easy to locate.

Naming Conventions

Establish clear naming conventions for include members to indicate their purpose and usage.

Access Control

Implement appropriate security controls to manage who can update JCL libraries.

Version Control

Maintain version history of include members to track changes and support rollback if needed.

A typical JCL library structure might include:

  • HLQ.GLOBAL.JCLLIB - Organization-wide standard includes
  • HLQ.DEPT.JCLLIB - Department-specific includes
  • HLQ.APP.JCLLIB - Application-specific includes
  • HLQ.USER.JCLLIB - User-specific testing includes

Using a consistent library hierarchy helps ensure that the most appropriate version of an include member is found first when multiple libraries are searched.

Advantages of Modular JCL

Breaking down JCL into modular, reusable components offers several advantages:

Reduced Maintenance Effort

When a change is needed, it can be made once in the include member rather than in multiple jobs.

Consistent Implementation

Standard processes are implemented the same way across all jobs that use the include member.

Simplified Job Development

Developers can focus on job-specific logic while reusing tested, proven components.

Easier Standardization

Organizational standards can be enforced by providing standard include members.

Improved Quality

Include members can be thoroughly tested and optimized, benefiting all jobs that use them.

Best Practices for JCL Reusability

Parameterization

Use symbolic parameters to make include members flexible and adaptable to different contexts:

jcl
1
2
3
4
5
6
// SET ENV=PROD // SET APP=PAYROLL // INCLUDE MEMBER=DBSETUP ... // In DBSETUP: //DB DD DSN=&ENV..&APP..DATABASE,DISP=SHR

Modularity

Create small, focused include members that do one thing well and can be combined as needed:

jcl
1
2
3
// INCLUDE MEMBER=DBCONNECT // INCLUDE MEMBER=SECURITY // INCLUDE MEMBER=LOGGING

Documentation

Include clear documentation within each include member:

jcl
1
2
3
4
5
6
7
8
9
10
//*-------------------------------------------------- //* DB2SETUP - Standard DB2 environment setup //* //* Parameters: //* &DBSYS - DB2 subsystem (default: DB01) //* &PLAN - Application plan name (required) //* //* Dependencies: //* Requires DB2 libraries to be available //*--------------------------------------------------

Consistent Naming

Use consistent, descriptive names for include members to indicate their purpose:

  • DB2SETUP - DB2 environment setup
  • GENDCAMS - Generic IDCAMS code
  • SORTDATA - Standard sort configuration
  • FTPSETUP - FTP environment setup

Testing

Thoroughly test include members before placing them in production libraries:

  1. Test the include member with different parameter values
  2. Verify behavior in different job contexts
  3. Validate error handling
  4. Document test cases and results

Real-World JCL Include Examples

Database Utility Setup

jcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//DBUTIL JOB (ACCT),'DB UTILITIES',CLASS=A // JCLLIB ORDER=(DBA.JCLLIB) // SET DBSYS=PROD // SET TABNAME=CUSTOMER //*-------------------------------------------------- // INCLUDE MEMBER=DBASETUP //*-------------------------------------------------- //STEP1 EXEC PGM=DSNUTILB,PARM='&DBSYS' //SYSPRINT DD SYSOUT=* //SYSIN DD * RUNSTATS TABLESPACE &TABNAME INDEX ALL UPDATE ACCESSPATH UPDATE SPACE /*

This example includes a standard database administration setup that might contain all the necessary DD statements for DB2 utilities.

Environment-Specific Configuration

jcl
1
2
3
4
5
6
7
8
9
//CONFIG JOB (ACCT),'CONFIG JOB',CLASS=A // JCLLIB ORDER=(APP.JCLLIB,ENV.JCLLIB) //*-------------------------------------------------- // SET ENV=PROD //*-------------------------------------------------- // INCLUDE MEMBER=&ENV.CONFIG //*-------------------------------------------------- //STEP1 EXEC PGM=APPRUN //...

This example dynamically includes a configuration based on the environment (using member names like PRODCONFIG, TESTCONFIG, etc.).

Standard Job Trailer

jcl
1
2
3
4
5
6
7
8
9
10
//MYJOB JOB (ACCT),'MY JOB',CLASS=A // JCLLIB ORDER=(STD.JCLLIB) //*-------------------------------------------------- // SET JOBNAME=MYJOB //*-------------------------------------------------- //STEP1 EXEC PGM=MYPROG //... //*-------------------------------------------------- // INCLUDE MEMBER=JOBEND //*--------------------------------------------------

This includes a standard job trailer that might contain notification steps, cleanup processing, or audit logging.

Reusable Error Handling

jcl
1
2
3
4
5
6
7
8
9
10
//MYJOB JOB (ACCT),'MY JOB',CLASS=A // JCLLIB ORDER=(STD.JCLLIB) //*-------------------------------------------------- //STEP1 EXEC PGM=MYPROG //... //*-------------------------------------------------- // IF STEP1.RC > 0 THEN // INCLUDE MEMBER=ERRORPROC // ENDIF //*--------------------------------------------------

This conditionally includes standardized error handling procedures when a step fails.

JCLLIB vs. Cataloged Procedures

While both JCLLIB/INCLUDE and cataloged procedures promote JCL reusability, they serve different purposes:

JCLLIB/INCLUDE

  • Inserts JCL fragments directly into the job stream
  • More flexible placement within a job
  • Can include partial JCL elements
  • Best for code fragments used in many contexts
  • Can be conditionally included

Cataloged Procedures

  • Called as a complete, self-contained unit
  • Can only be invoked with EXEC statements
  • Must contain complete steps
  • Best for standardized processing sequences
  • Parameter passing is more structured

In practice, many organizations use both approaches together, leveraging the strengths of each:

jcl
1
2
3
4
5
6
7
8
9
10
//MYJOB JOB (ACCT),'MY JOB',CLASS=A // JCLLIB ORDER=(STD.JCLLIB) //*-------------------------------------------------- // INCLUDE MEMBER=STDSETUP //*-------------------------------------------------- //STEP1 EXEC MYPROC //... //*-------------------------------------------------- // INCLUDE MEMBER=CLEANUP //*--------------------------------------------------

Common Challenges and Solutions

Practical Exercise

Building a Modular JCL Framework

Design a modular JCL framework for a data processing application using include members. The framework should support:

  1. Environment-specific configuration (DEV/TEST/PROD)
  2. Standard error handling and reporting
  3. Common setup for database access
  4. Flexible file processing with parameter-driven behavior
  5. Standardized job beginning and ending procedures

Create include members for:

  • Environment configuration (one for each environment)
  • Error handling procedures
  • Database connection setup
  • Standard file processing
  • Job initialization and cleanup

Then create a job that uses these include members to demonstrate the framework.

Consider how you would:

  • Structure the include libraries
  • Design parameters for maximum flexibility
  • Document the framework for users
  • Implement version control and change management

Try designing this framework yourself, then compare with sample solutions in a future lesson.

Test Your Knowledge

1. What is the primary purpose of the JCLLIB statement?

  • To create copies of JCL procedures
  • To specify additional libraries where procedures might be found
  • To include JCL fragments directly into a job stream
  • To create backups of JCL code

2. Where must the JCLLIB statement be placed in a JCL job?

  • Before the JOB statement
  • After the JOB statement but before any EXEC statements
  • After any EXEC statements
  • Anywhere in the job stream

3. What does the INCLUDE statement do in JCL?

  • Creates a copy of a cataloged procedure
  • Specifies a library search order
  • Inserts predefined JCL code fragments from a library
  • Combines multiple jobs into one

4. Which statement correctly uses the JCLLIB statement?

  • //MYJOB JCLLIB ORDER=(USER.PROCLIB,SYS1.PROCLIB)
  • //MYJOB JOB (ACCT),"NAME" // JCLLIB ORDER=(USER.PROCLIB,SYS1.PROCLIB)
  • //PROC1 JCLLIB ORDER=(USER.PROCLIB)
  • //STEP1 EXEC JCLLIB=(USER.PROCLIB,SYS1.PROCLIB)

5. What happens if you do not specify a JCLLIB statement in your job?

  • The job fails with a JCL error
  • The system uses only SYS1.PROCLIB for procedure resolution
  • The system searches the standard system procedure libraries in the default order
  • All procedures must be included as in-stream procedures

Frequently Asked Questions