Description
In JTOpen, PcmlProgram.callProgram() enforces a hard-coded limit of 7 or fewer parameters for service program (*SRVPGM) calls, regardless of the target IBM i system's version/release/modification (VRM). This limit is stale: on IBM i 7.3 and 7.4 (with PTFs SI75449/SI75397) and later releases, QZRUCLSP supports up to 248 parameters.
As a result, PCML-based service program calls fail with a TOO_MANY_PARMS exception when 8–248 parameters are defined, even though the underlying system fully supports them. The correct, VRM-aware approach already exists in ServiceProgramCall.run() and should be mirrored in PcmlProgram.
Steps to Reproduce
- Target an IBM i system at VRM > 7.2 (e.g., 7.3 with the required PTFs, 7.4, or 7.5).
- Define a PCML document with a
<program> element pointing to a *SRVPGM with an entrypoint, declaring more than 7 parameters (e.g., 10).
- Invoke the program via
ProgramCallDocument.callProgram().
- The call fails before it is ever sent to the system.
Expected Behavior
For systems at VRM > 7.2, PcmlProgram should allow up to 248 parameters for service program calls. When more than 7 parameters are used, each parameter must be passed by reference (pointer) — matching the rule enforced in ServiceProgramCall.
Actual Behavior
PcmlProgram unconditionally rejects any service program call with more than 7 parameters, throwing:
PcmlException (DAMRI.TOO_MANY_PARMS)
Root Cause Analysis
File: com/ibm/as400/data/PcmlProgram.java
Method: callProgram()
Lines: ~519–525
The parameter-count check is hard-coded to 7 and does not consider the host VRM:
// Service programs can only have 7 or fewer parameters (this is a server limitation).
// Note: This check does not take into account that minvrm= and maxvrm=
// can reduce the number of parameters at runtime
if ( getNbrChildren() > 7 ) // @D1A
{
throw new PcmlException(DAMRI.TOO_MANY_PARMS, new Object[] {makeQuotedAttr("entrypoint", m_EntrypointStr), Integer.valueOf(7), getBracketedTagName(), getNameForException()} ); // @D1A
}
By contrast, ServiceProgramCall.run() (lines ~307–332) already implements the correct, VRM-aware logic:
//@AE2 For 7.4 and 7.3, QZRUCLSP PTF SI75449 and SI75397 supports 248 parameters.
if (system_.getVRM() > 0x00070200) {
if (parameterList_.length > 248) {
Trace.log(Trace.ERROR, "Parameter list length exceeds limit of 248 parameters:", parameterList_.length);
throw new ExtendedIllegalArgumentException("parameterList.length (" + parameterList_.length + ")", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
if (parameterList_.length > 7) {
for (int i = 0; i < parameterList_.length; ++i) {
int parameterType = parameterList_[i].getParameterType();
if (parameterType != 2) { // must be pass-by-reference (pointer)
Trace.log(Trace.ERROR, "Parameter list length is larger than 7 parameters, all parameters must be passed as pointers. The parameter ", i);
throw new ExtendedIllegalArgumentException("The parameter [" + i + "]", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
}
}
} else {
if (parameterList_.length > 7) {
Trace.log(Trace.ERROR, "Parameter list length exceeds limit of 7 parameters:", parameterList_.length);
throw new ExtendedIllegalArgumentException("parameterList.length (" + parameterList_.length + ")", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
}
PcmlProgram has access to the system object (as400, used a few lines later at as400.getCcsid()), so the host VRM is readily available via as400.getVRM().
Proposed Fix
Replace the hard-coded > 7 check in PcmlProgram.callProgram() with the same VRM-aware logic used in ServiceProgramCall.run():
- If host VRM > 0x00070200: allow up to 248 parameters; when more than 7, require every parameter to be passed by reference (pointer). Otherwise throw
TOO_MANY_PARMS.
- If host VRM ≤ 0x00070200: keep the existing 7-parameter limit.
if ( getPath().toUpperCase().endsWith(".SRVPGM") )
{
if (getEntrypoint() == null)
{
throw new PcmlException(DAMRI.NO_ENTRYPOINT, new Object[] {makeQuotedAttr("entrypoint", m_EntrypointStr), getBracketedTagName(), getNameForException()} );
}
// For 7.3/7.4 (QZRUCLSP PTF SI75449/SI75397) and later, up to 248 parameters are supported.
// When more than 7 parameters are used, all must be passed by reference (pointer).
if (as400.getVRM() > 0x00070200)
{
if ( getNbrChildren() > 248 )
{
throw new PcmlException(DAMRI.TOO_MANY_PARMS, new Object[] {makeQuotedAttr("entrypoint", m_EntrypointStr), Integer.valueOf(248), getBracketedTagName(), getNameForException()} );
}
// (When >7 parameters, validate that each child parameter is passed by reference,
// mirroring ServiceProgramCall's pointer-type check.)
}
else if ( getNbrChildren() > 7 )
{
throw new PcmlException(DAMRI.TOO_MANY_PARMS, new Object[] {makeQuotedAttr("entrypoint", m_EntrypointStr), Integer.valueOf(7), getBracketedTagName(), getNameForException()} );
}
}
Why this is safe:
| Scenario |
Behavior |
| VRM ≤ 7.2, ≤ 7 parameters |
Allowed (unchanged) |
| VRM ≤ 7.2, > 7 parameters |
TOO_MANY_PARMS with limit 7 (unchanged) |
| VRM > 7.2, ≤ 7 parameters |
Allowed (unchanged) |
| VRM > 7.2, 8–248 parameters (all by reference) |
Allowed (newly enabled, matches ServiceProgramCall) |
| VRM > 7.2, > 248 parameters |
TOO_MANY_PARMS with limit 248 |
Versions
- Affected: all versions where
PcmlProgram retains the hard-coded 7-parameter limit (@D1A).
- Reference implementation:
ServiceProgramCall (@AE2) already handles this correctly.
Environment
- IBM i (AS/400) target system at VRM > 7.2 (7.3 with SI75449/SI75397, 7.4, 7.5)
- Service program (
*SRVPGM) calls via PCML (ProgramCallDocument)
- Java 8+ runtime
Description
In JTOpen,
PcmlProgram.callProgram()enforces a hard-coded limit of 7 or fewer parameters for service program (*SRVPGM) calls, regardless of the target IBM i system's version/release/modification (VRM). This limit is stale: on IBM i 7.3 and 7.4 (with PTFs SI75449/SI75397) and later releases,QZRUCLSPsupports up to 248 parameters.As a result, PCML-based service program calls fail with a
TOO_MANY_PARMSexception when 8–248 parameters are defined, even though the underlying system fully supports them. The correct, VRM-aware approach already exists inServiceProgramCall.run()and should be mirrored inPcmlProgram.Steps to Reproduce
<program>element pointing to a*SRVPGMwith anentrypoint, declaring more than 7 parameters (e.g., 10).ProgramCallDocument.callProgram().Expected Behavior
For systems at VRM > 7.2,
PcmlProgramshould allow up to 248 parameters for service program calls. When more than 7 parameters are used, each parameter must be passed by reference (pointer) — matching the rule enforced inServiceProgramCall.Actual Behavior
PcmlProgramunconditionally rejects any service program call with more than 7 parameters, throwing:Root Cause Analysis
File:
com/ibm/as400/data/PcmlProgram.javaMethod:
callProgram()Lines: ~519–525
The parameter-count check is hard-coded to 7 and does not consider the host VRM:
By contrast,
ServiceProgramCall.run()(lines ~307–332) already implements the correct, VRM-aware logic:PcmlProgramhas access to the system object (as400, used a few lines later atas400.getCcsid()), so the host VRM is readily available viaas400.getVRM().Proposed Fix
Replace the hard-coded
> 7check inPcmlProgram.callProgram()with the same VRM-aware logic used inServiceProgramCall.run():TOO_MANY_PARMS.Why this is safe:
TOO_MANY_PARMSwith limit 7 (unchanged)ServiceProgramCall)TOO_MANY_PARMSwith limit 248Versions
PcmlProgramretains the hard-coded 7-parameter limit (@D1A).ServiceProgramCall(@AE2) already handles this correctly.Environment
*SRVPGM) calls via PCML (ProgramCallDocument)