

After careful consideration, we have made the decision to close new customer access to **AWS Mainframe Modernization self-managed experience**, effective June 30, 2026. Existing customers can continue to use the service as normal. AWS continues to invest in security and availability improvements for AWS Mainframe Modernization self-managed experience, but we do not plan to introduce new features. For more information, see [AWS Mainframe Modernization availability change](https://docs.aws.amazon.com/m2/latest/userguide/mainframe-modernization-availability-change.html). 

**AWS Mainframe Modernization Service (Managed Runtime Environment experience)** is no longer open to new customers. For capabilities similar to AWS Mainframe Modernization Service (Managed Runtime Environment experience) explore AWS Mainframe Modernization Service (Self-Managed Experience). Existing customers can continue to use the service as normal. For more information, see [AWS Mainframe Modernization availability change](https://docs.aws.amazon.com/m2/latest/userguide/mainframe-modernization-availability-change.html). 

# Commands Utilities
<a name="system-commands-utilities"></a>

This section is related to utility programs whose role is to handle user commands, provided using control cards.

## IKJEFT1A/IKJEFT1B/KEQEFT01/IKJEFT01/DSNDBTCH
<a name="ikjeft1a-ikjeft1b-keqeft01-ikjeft01-dsndbtch"></a>

### IKJEFT1A Purpose
<a name="ikjeft1a-purpose"></a>

IKJEFT1A and its aliases execute TSO (**T**ime **S**haring **O**ption) commands in batch jobs without requiring an interactive TSO session, bridging non-interactive batch and interactive TSO environments.

Mimics legacy IKJEFT1A behavior with environment-specific differences: for instance, DB2 TERM(inate) commands are ignored on modern environments (logged as informational).

**Note**  
Command syntax not detailed here - IKJEFT1A uses legacy command datasets unchanged. Please refer to legacy platform documentation for TSO command details.

### IKJEFT1A Signature
<a name="ikjeft1a-signature"></a>

Uses `SYSTSIN` dataset for command input (defined via JCL `DD` directive). Modernized version uses the same dataset unchanged. Invoked only in modernized Groovy jobs scripts.

### IKJEFT1A related configuration parameters
<a name="ikjeft1a-configuration"></a>

The behaviour of the utility is influenced by the following configuration parameter:
+ `systin.encoding`

Please see [Available properties for optional web applications](ba-runtime-key-value.md#ba-runtime-key-value-web) for details about configuring this parameter.

### IKJEFT1A Checks/Error handling
<a name="ikjeft1a-error-handling"></a>

When an unsupported command is present in the SYSTSIN dataset then a `RuntimeException` is thrown.

### IKJEFT1A Sample usages
<a name="ikjeft1a-sample-usages"></a>

The legacy JCL script (which uses an inlined content of the `SYSTSIN` dataset, using `DD *` directive)

```
//*********************************************************************         
//* READ THE TEMPORARY INPUT FILE                                     *         
//*********************************************************************         
// IF IDCM00032.RC = 1 THEN                                                    
//067FILEKEY  EXEC PGM=IKJEFT01,DYNAMNBR=20                                     
//SYSTSIN   DD *                                                                
 DSN SYSTEM(DB2P)                                                               
 RUN  PROGRAM(067-fileKey) PLAN(FILEKEYPLAN)    PARM('RT')                      
 END                                                                            
/*                                                                              
//TEMPVSAM  DD DSN=IDXVIDEO.TEMPVSAM,DISP=SHR                                   
//FKOUT     DD DSN=output(out067.txt),DISP=(NEW,CATLG)                          
// ENDIF                                                                        
//*********************************************************************
```

and the matching modernized script (in groovy) -- the inlined content of `SYSTSIN` dataset is represented by a "stream" --

```
// STEP 067FILEKEY - PGM - IKJEFT01***********************************************
def step067FILEKEY(Object shell, Map params, Map programResults){
    shell.with {
        if (checkValidProgramResults(programResults)) {
            return execStep("067FILEKEY", "IKJEFT01", programResults, {
                mpr
                    .withFileConfigurations(new FileConfigurationUtils()
                        .withJobContext(jobContext)
                        .fileSystem("SYSTSIN")
                        .stream(
""" DSN SYSTEM(DB2P)                                                               
 RUN  PROGRAM(067-fileKey) PLAN(FILEKEYPLAN)    PARM('RT')                      
 END
""", getEncoding())
                        .build()
                        .bluesam("TEMPVSAM")
                        .dataset("IDXVIDEO.TEMPVSAM")
                        .disposition("SHR")
                        .build()
                        .fileSystem("FKOUT")
                        .path("output(out067.txt)")
                        .disposition("NEW")
                        .normalTermination("CATLG")
                        .build()
                        .getFileConfigurations())
                    .withParameters(params)
                    .runProgram("IKJEFT01")
                })
        }
    }
}
```

## QCMDEXC
<a name="qcmdexc"></a>

### QCMDEXC Purpose
<a name="qcmdexc-purpose"></a>

This utility program emulates the behaviour of the AS/400 system utility QCMDEXC, used to run system commands in a dynamic way at runtime.

Features:
+ Parses and executes commands dynamically.
+ Supports named and positional parameter formats.

### QCMDEXC Signature
<a name="qcmdexc-signature"></a>

Accepts 1-2 parameters:
+ First: Alphanumeric data containing commands to execute
+ Second (optional): length in bytes to read from first parameter (defaults to full length)

### QCMDEXC Checks/Error handling
<a name="qcmdexc-error-handling"></a>

For the following cases, a `RuntimeException` will be thrown:
+ When the number of provided arguments is not one or two;
+ If the commands argument is empty or if the command to be run is unrecognized;
+ If the command run fails for any reason; in addition, the return code from the program will be set to 1.

### QCMDEXC Sample usages
<a name="qcmdexc-sample-usages"></a>

Here is a sample usage from a legacy COBOL program: the data item `CL-COMMANDX` is fitted with commands before being used as argument for the QCMDEXC program call:

```
       INITIALIZE CL-COMMANDX.                                      
                                                               
       STRING                                                       
           "CPYF FROMFILE(PLAYERS) TOFILE(" DELIMITED BY SIZE,            
           "NEWFILE"                      DELIMITED BY SIZE,        
           ") MBROPT(*REPLACE) FMTOPT(*NOCHK) CRTFILE(*YES)"        
                                          DELIMITED BY SIZE         
           INTO CL-COMMANDX                                         
       END-STRING.                                                  
                                                               
       CALL "QCMDEXC"                  USING CL-COMMANDX            
                                             CLENGTHX.
```

Once modernized into java code, this becomes:

```
    DataUtils.initialize(ctx.getClCommandx().getClCommandxReference());
    StringConcatenationBuilder.newInstance(ctx.getClCommandx().getClCommandxReference())
        .addDelimitedBySize("CPYF FROMFILE(PLAYERS) TOFILE(")
        .addDelimitedBySize("NEWFILE")
        .addDelimitedBySize(") MBROPT(*REPLACE) FMTOPT(*NOCHK) CRTFILE(*YES)")
        .end();
    ctrl.callSubProgram("QCMDEXC", CallBuilder.newInstance()
        .byReference(ctx.getClCommandx().getClCommandxReference())
        .byReference(ctx.getClengthx().getClengthxReference())
        .getArguments(), ctx);
```

Please note that legacy commands contents are being used "as-is" in the modernized code, without any modification.