Learn about signatures, binder language, and more.
Editor's note: This article is excerpted from Programming in ILE RPG, Fifth Edition (MC Press, 2015), chapter 15, "Building and Using Service Programs."
To modify the code in a service program procedure, you must go through the same compile-then-bind process to apply those changes to the service program. Instead of recreating the entire service program, though, you can use the UPDSRVPGM (Update Service Program) command to complete an abbreviated binding step. The UPDSRVPGM command lets you list just the module (or modules) that you want to remove from the original service program, replacing its code with the new version that now resides in the newly recompiled module. Figure 15.6 illustrates the prompted UPDSRVPGM command.
Figure 15.6: UPDSRVPGM (Update Service Program) command
The UPDSRVPGM command performs the same functions as the CRTSRVPGM command, except that it replaces only the changed modules (i.e., those you list) in an existing service program. The unchanged modules are unaffected.
15.5.1. Service Program Signatures
If you make a change to a service program that does not affect its external interface (i.e., you don't change its exported procedures, or the procedures' parameters or return value), the programs that use that service program require no action on your part to reflect the change. This advantage is key to service programs. Even though a service program may have hundreds of client programs, they may not require any maintenance to support the updated service program. Whether you must rebind those client programs depends upon the service program signature. The signature is a service program attribute that identifies its external interface—the exported procedures (and data items) it contains.
The signature is a property that is stored with the service program; its identity is usually a system-generated string. When you bind a service program to a client, the client makes a note of the service program's signature. At runtime when the client is loading itself and any associated service programs, it checks each service program to ensure that it still supports the signature the client is expecting. When the signatures in the client and the service program match, the client can use the service program. A mismatch, however, causes the program load to fail.
The service program has only one current signature, but it can retain many previous signatures, representing many different public interfaces. When you bind a service program to a client, the binder associates the two objects by using the current signature. But if any clients exist that know the service program by a previous signature, those programs can continue to use the service program without recompiling or rebinding. The DSPSRVPGM command (Figure 15.7) shows all of its valid signatures.
Figure 15.7: DSPSRVPGM DETAIL(*SIGNATURE)
To understand why you might want a service program to have multiple signatures, consider a hypothetical service program, WWWRPG. When first created, the service program contained only four procedures (their functions are not relevant to this discussion):
- WWWDECODE
- WWWDUMP
- WWWECHO
- WWWEXTRACT
If this service program were in use for some time, it probably had many programs using its four exported procedures. At some point, it might be desirable to create new procedures and package them within the service program. For example, you might to add the following procedures to the service program:
- WWWGETDOC
- WWWGETENV
- WWWGETIFS
You could code this procedure in additional Nomain modules and then bind them to the WWWRPG service program. To avoid having to rebind all the existing client programs that use WWWRPG—but that do not use the new procedures—the service program needs to have two signatures. The current signature would support all seven exported procedures, but the older previous signature would support only the original four procedures. To enable this scenario, ILE allows you to manage the service program signatures by using a feature called binder language.
15.5.2. Using Binder Language
Binder language is a special syntax that consists of commands to describe a service program's external interface. Using an editor, you enter these commands into a source member (source type BND) and then refer to that source member when you create the service program. Although you do not compile the binder language source, the binder incorporates it into the algorithm it uses to create the service program signature. There are three binder language commands:
- STRPGMEXP (Start Program Export List)
- EXPORT (Export a Program Symbol)
- ENDPGMEXP (End Program Export List)
To understand how binder language relates to the service program signature, consider the hypothetical service program WWWRPG described earlier. When first created, the service program contained four procedures, compiled to *Module objects. Before binding the service program, you should create a new source member to store the binder language that will define the service program signature. Usually, you name the source member the same as the service program, WWWRPG in this example:
STRPGMEXP PGMLVL(*CURRENT)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
ENDPGMEXP
The STRPGMEXP binder language statement forms the beginning of the binder language to define a service program signature. Specifying PGMLVL(*CURRENT), the default value, indicates that the signature is to be the current signature. In this example, the system automatically generates a signature identifier by default. The ENDPGMEXP statement indicates the end of the signature.
Between the beginning and the ending statements, EXPORT statements list the procedures to include in the signature. The order of the procedures in the export block affects the signature, so you should not change the order after you have created the service program. In addition, you must have created the procedures with the Export keyword in the ILE RPG source. In the rare case that the procedure names are case sensitive, you must enclose the names between apostrophes (').
You cannot compile the binder language source member. Instead, you refer to it when you create the service program:
CRTSRVPGM SRVPGM(WWWRPG) +
MODULE(WWWDECODE WWWDUMP WWWECHO WWWEXTRACT) +
EXPORT(*SRCFILE) +
SRCFILE(QSRVSRC) +
SRCMBR(WWWRPG)
Figures 15.1 and 15.6 illustrate the EXPORT, SRCFILE, and SRCMBR parameters. Specifying EXPORT(*SRCFILE) tells the binder that it will generate the service program signature by using binder language. The SRCFILE and SRCMBR parameters identify the location of the binder language.
After the service program is created, you can view the resulting signature by using the DSPSRVPGM (Display Service Program) command. The signature is a system-generated 16-byte string, as Figure 15.7 shows. When you bind this service program to a client program, the client also stores the current signature from the service program. When the client and the service program are loaded at runtime, their signatures must match. To view the service programs used by the client, along with their expected signatures, you can use the DSPPGM (Figure 15.4) or DSPSRVPGM command, depending upon the caller's object type.
The use of binder language goes well beyond using it to create a single signature for a service program. As you add new procedures to a service program, binder language manages not only the service program's new current signature, but it also supports its previous signatures. So, if any clients know the service program by a previous signature, those callers can continue to use the service program without recompiling or rebinding. For example, with the hypothetical WWWRPG scenario, when you want to add three new procedures to the service program, you must first make changes to the service program's binder language:
STRPGMEXP PGMLVL(*CURRENT)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
EXPORT SYMBOL(WWWGETDOC)
EXPORT SYMBOL(WWWGETENV)
EXPORT SYMBOL(WWWGETIFS)
ENDPGMEXP
STRPGMEXP PGMLVL(*PRV)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
ENDPGMEXP
This binder language now supports two signatures. The second signature is the original signature, but it has now been changed to be the previous signature: PGMLVL(*PRV). The new current signature is the same as the original signature, but with the three new procedures added to the end. You should not remove or rearrange entries in existing binder language export blocks. The current signature's export block must contain the same procedures in the same order as previous export blocks. You add new procedures only to the end of the block.
When you recreate the service program, it will support both signatures. Clients that know the service program by its old signature continue to run without changes. When you associate a new client with the service program, or rebind an existing client, it will use the current signature.
As you add new procedures to the service program, adding those procedures to the signature by using binder language is simple:
STRPGMEXP PGMLVL(*CURRENT)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
EXPORT SYMBOL(WWWGETDOC)
EXPORT SYMBOL(WWWGETENV)
EXPORT SYMBOL(WWWGETIFS)
EXPORT SYMBOL(WWWMAPQRY)
EXPORT SYMBOL(WWWREAD)
EXPORT SYMBOL(WWWREPLACE)
ENDPGMEXP
STRPGMEXP PGMLVL(*PRV)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
EXPORT SYMBOL(WWWGETDOC)
EXPORT SYMBOL(WWWGETENV)
EXPORT SYMBOL(WWWGETIFS)
ENDPGMEXP
STRPGMEXP PGMLVL(*PRV)
EXPORT SYMBOL(WWWDECODE)
EXPORT SYMBOL(WWWDUMP)
EXPORT SYMBOL(WWWECHO)
EXPORT SYMBOL(WWWEXTRACT)
ENDPGMEXP
If, in the future, you do not want to support a previous signature, simply remove the entire signature from the binder language and update the service program (UPDSRVPGM command). Then, any clients that are still using the outdated signature will no longer run until they are rebound.
You can also explicitly name a service program signature, instead of letting the system automatically generate one. In the binder language, specify a SIGNATURE value when you start the export block:
STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(WWWRPG)
The explicit signature should be 16 or fewer characters. If you name the signature, your binder language source needs only one export block and one signature. You can add new procedures to the end of the lone export block, and existing programs will still run.
Note: A service program signature is a means of listing the exported procedures and data items from a service program. It does not ensure that the interface to a particular procedure in the service program is valid. If you make changes to the parameters or return value in a procedure, those changes can render the procedure incompatible with existing clients, regardless of the signature. In that case, you must rebind all the clients by using CRTPGM or CRTSRVPGM.
LATEST COMMENTS
MC Press Online