Here's a realistic scenario where a wrong or mismatched activation group causes a runtime error like:
RNX1217 โ Program or service program not found
RNX1216 โ Level check or file already open error
…and how changing the activation group resolves it.
๐งจ Scenario: Activation Group Mismatch Causes Crash
You have:
-
A main RPG program (
CUSTOMERPGM) compiled withACTGRP('CUSTGRP') -
A service program (
CUSTSRVPGM) compiled withACTGRP(*CALLER) -
A batch CL job or API call that runs
CUSTOMERPGMtwice
๐ Problem Flow
First Call:
CALL PGM(CUSTOMERPGM)
-
Activation group
CUSTGRPis created -
CUSTOMERPGMruns -
CUSTSRVPGMruns insideCUSTGRP(because it uses*CALLER) -
All files and globals stay open
Second Call (same job):
CALL PGM(CUSTOMERPGM)
Now the system tries to:
-
Load
CUSTOMERPGMintoCUSTGRPagain -
Rebind
CUSTSRVPGM— but it's already loaded -
Reopen files already open → file already open error or level check error
๐ฃ Result: Crash
-
You get:
-
RNX1216(file open or level check) -
Or
RNX1217(binding issue)
-
-
Especially if files changed between runs or you recompiled only one component
โ
Fix: Change ACTGRP(*NEW) in Main Program
In CUSTOMERPGM:
ctl-opt actgrp(*new);
Now, every call to the program:
-
Creates a new activation group
-
Loads fresh copies of service programs and files
-
No residual memory or bindings from the previous call
โ
Alternative Fix: Use RCLACTGRP
If you want to keep using a named group (CUSTGRP) but reset it before rerun:
RCLACTGRP ACTGRP(CUSTGRP)
CALL PGM(CUSTOMERPGM)
๐ง Takeaway
| Problem | Fix |
|---|---|
| Reusing a named group causes errors | Use *NEW to isolate memory |
| Files or service programs stay loaded | Use *CALLER and control cleanup properly |
| Need to fully reset environment | Use RCLACTGRP to clear memory |
Would you like a CL wrapper that auto-recalls RCLACTGRP before each call to ensure fresh execution — especially useful in API or batch chains?