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
CUSTOMERPGM
twice
๐ Problem Flow
First Call:
CALL PGM(CUSTOMERPGM)
-
Activation group
CUSTGRP
is created -
CUSTOMERPGM
runs -
CUSTSRVPGM
runs insideCUSTGRP
(because it uses*CALLER
) -
All files and globals stay open
Second Call (same job):
CALL PGM(CUSTOMERPGM)
Now the system tries to:
-
Load
CUSTOMERPGM
intoCUSTGRP
again -
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?