I have talked about service programs in the past and, at the time, I mentioned that you need a binding source without really saying why. So, to revisit the subject, using the binding language allows you to change your service program without needing to recompile all of the programs that reference it.
It all comes down to signatures.
You can display the signature of a service program using the following command (adjust for your own library and service program, obviously):
DSPSRVPGM SRVPGM(LSCLIB/LSSUTIL) DETAIL(*SIGNATURE)
This will display a screen similar to the one below:
Display Service Program Information Display 1 of 1 Service program . . . . . . . . . . . . : LSSUTIL Library . . . . . . . . . . . . . . . : LSCLIB Owner . . . . . . . . . . . . . . . . . : QPGMR Service program attribute . . . . . . . : RPGLE Detail . . . . . . . . . . . . . . . . . : *SIGNATURE Signatures: 62C9C0FAA16B653C4359413F3E9CEB81
Now take a look at any program that references the service program:
DSPPGM PGM(LSCLIB/LS0190R) DETAIL(*SRVPGM)
Will something like this:
Display Program Information Display 1 of 1 Program . . . . . . . : LS0190R Library . . . . . . . : LSCLIB Owner . . . . . . . . : QPGMR Program attribute . . : RPGLE Detail . . . . . . . . : *SRVPGM Type options, press Enter. 5=Display Service Opt Program Library Activation Signature LSSUTIL *LIBL *IMMED 62C9C0FAA16B653C4359413F3E9CEB81 QRNXIE QSYS *IMMED D8D9D5E7C9C540404040404040404040 QRNXIO QSYS *IMMED D8D9D5E7C9D640404040404040404040 QLEAWI QSYS *IMMED 44F70FABA08585397BDF0CF195F82EC1
Note that the signqture of the service program needs to match the signature the referencing program expects, and if they don’t you will waste a day dealing with signature violation errors.
So if I want to add a procedure to a service program (which will change the service program’s signature) without having to identify and recompile every program that refers to it, I need to make use of the binder language.
I generally create the binder language source manually but, if you don’t have this, you can use the RTVBNDSRC
command. To retrieve the source for service program LSSUTIL in library LSCLIB you would do this:
RTVBNDSRC SRVPGM(LSCLIB/LSSUTIL) SRCFILE(LSCLIB/QSRVSRC) MBROPT(*ADD)
Then go and look at your binder source and you will a listing of all your exported procedures in a format that looks see something like this:
STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(X'62C9C0FAA16B653C4359413F3E9CEB81') /********************************************************************/ /* *MODULE LSSUTIL LSCLIB 08/02/18 10:49:27 */ /********************************************************************/ EXPORT SYMBOL("GETCORRECTION") EXPORT SYMBOL("GETERRTEXT") ENDPGMEXP
Just to tidy things up a bit, move the comment lines to the top and get rid of the SIGNATURE keyword (it’s the PGMLVL that you really need) so that the source now looks like this:
/********************************************************************/ /* *MODULE LSSUTIL LSCLIB 08/02/18 10:49:27 */ /********************************************************************/ STRPGMEXP PGMLVL(*CURRENT) EXPORT SYMBOL("GETCORRECTION") EXPORT SYMBOL("GETERRTEXT") ENDPGMEXP
Now you want to tell it that this is the old version and the new current version of the service program contains your shiny new procedure. This is how:
/********************************************************************/ /* *MODULE LSSUTIL LSCLIB 08/02/18 10:49:27 */ /********************************************************************/ STRPGMEXP PGMLVL(*CURRENT) EXPORT SYMBOL("GETCORRECTION") EXPORT SYMBOL("GETERRTEXT") EXPORT SYMBOL("GETSHINY") ENDPGMEXP /********************************************************************/ STRPGMEXP PGMLVL(*PRV) EXPORT SYMBOL("GETCORRECTION") EXPORT SYMBOL("GETERRTEXT") ENDPGMEXP /********************************************************************/
Then create your service program using:
CRTSRVPGM SRVPGM(LSCLIB/LSSUTIL) MODULE(LSCLIB/LSSUTIL) SRCFILE(LSCLIB/QSRVSRC) SRCMBR(LSSUTIL)
And display the service program signatures:
DSPSRVPGM SRVPGM(LSCLIB/LSSUTIL) DETAIL(*SIGNATURE)
And here’s what you should have:
Display Service Program Information Display 1 of 1 Service program . . . . . . . . . . . . : LSSUTIL Library . . . . . . . . . . . . . . . : LSCLIB Owner . . . . . . . . . . . . . . . . . : QPGMR Service program attribute . . . . . . . : RPGLE Detail . . . . . . . . . . . . . . . . . : *SIGNATURE Signatures: 2C9C0F7DED8A1897F656D6C9CBB17DDD 62C9C0FAA16B653C4359413F3E9CEB81
The service program now has two signatures. The new one is at the top of the list and the previous one is below it. What’s more, I can specify PGMLVL(*PRV)
as many times as I need to.
When a program uses the service program, it will look down the list until it finds a signature that matches to identify the list of modules it can use. And this means that you can change your service program as much and as many times as you like without needing to worry about any of the programs that uses it.
A final note
You only need to change your binding source when you change the list of exported procedures (generally by adding a new procedure). Changing an existing procedure won’t impact your signatures.
A final final note
When you do add a new procedure, always add it to the bottom.