ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Service program always has random signature

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Service program always has random signature

    We have a service program with 160ish modules, created last year. We do use binding source with it.
    Whenever we add modules/procedures to it, we have to recompile everything that uses it because it always generates a new random signature, instead of respecting the binding source

    We cannot work out why

    I noticed today that there were several problems with the binding source:
    * DSPSRVPGM listed export procedures that were missing from the binding source
    * DSPSRVPGM listed export variables (data items) that were missing from the binding source
    * There were procedures in the binding source that did not exist in the bound modules

    I fixed all that, and it did not fix the signature.

    I even tried using RTVBNDSRC to generate the binding source from the service program, changed the signature, and then recreated the service program using that source, and it still did not work.

    Does anyone know what I may be missing?

  • #2
    Please post the beginning of your binder source.
    Did you define a fix signature in the SRTPGMEXP Command and/or do you keep your previous binder blocks (STRPGMEXPR, EXPORT, ENDPGMEXP) in your source?
    Something like this:

    Code:
    STRPGMEXP PGMLVL(*CURRENT) LVLCHK(*YES) +               
    SIGNATURE('MYSIGNATURE')                                         
    EXPORT SYMBOL(CVTDATE2NUM)                              
    EXPORT SYMBOL(CVTNUM2DATE)                              
    ENDPGMEXP
    or Something like this
    Code:
    STRPGMEXP PGMLVL(*CURRENT) LVLCHK(*YES) +               
    SIGNATURE(*GEN)                                         
    EXPORT SYMBOL(CVTDATE2NUM)                              
    EXPORT SYMBOL(CVTNUM2DATE)                              
    ENDPGMEXP
    
    STRPGMEXP PGMLVL(*PRV) LVLCHK(*YES) +               
    SIGNATURE(*GEN)                                         
    EXPORT SYMBOL(CVTDATE2NUM)                              
    ENDPGMEXP
    If you did not specify a signature, i.e. SIGNATURE is *GEN, then you need to keep the previous binder blocks in your source and only change the PGMLVL for this block to *PRV.
    If you keep all your previous blocks, then multiple signatures based on the previous blocks are determined and included in the service program.
    If a program includes an older signature, the service program can be found, because it includes the previous signature, too.

    Birgitta

    Comment


    • #3
      Using *PRV and having multiple blocks of listed exports gets to be a hassle and the binder source gets very long very quickly.

      I use Birgitta's first example above, explicitly naming the signature and never changing it. Then you only have to maintain one list of exported procedures instead of multiple blocks. Mine all look like this example below, and I include some notes at the top to let the programmers know the 'rules' so that things don't get all hosed up:

      Code:
      /*==================================================================*/
      /* Name        : SRVDATTM                                           */
      /* Description : Binder Source for SRVDATTM service program         */
      /* Created By  : Programmer Name                                    */
      /* Date Created: mm/dd/yyyy                                         */
      /* Narrative:    Binder source for service program SRVDATTM         */
      /*               containing all exported procedures from the        */
      /*               service program.                                   */
      /*------------------------------------------------------------------*/
      /* Rules:                                                           */
      /*               1. Never change the Signature ('SRVDATTM')         */
      /*               2. Never change the order of exports               */
      /*               3. Add new exports at the end of the export list   */
      /* Example:                                                         */
      /*   To add new procedures for a new caller without having to       */
      /*   recompile all the programs that use service program SRVDATTM,  */
      /*   1.  Add the new procedures AT THE BOTTOM of the export list.   */
      /*   2.  Use UPDSRVPGM to update Service Program SRVDATTM and       */
      /*       generate the new exports.                                  */
      /*==================================================================*/
         StrPgmExp  PgmLvl(*Current) Signature('SRVDATTM')                  
            Export Symbol(getBegOfMonth)                           /*   1 */
            Export Symbol(getEndOfMonth)                           /*   2 */
            Export Symbol(getDayOfWeek)                            /*   3 */
            Export Symbol(getDayName)                              /*   4 */
            Export Symbol(getMonthName)                            /*   5 */
         Endpgmexp

      Comment


      • #4
        it's something of a saga

        Currently the binding source has a current block and 4 previous blocks. headers for all 4 below

        strpgmexp pgmlvl(*current) signature('version_04_28092017')
        export symbol...
        endpgmexp

        strpgmexp pgmlvl(*prv) signature('version 03 25012017')
        export symbol...
        endpgmexp

        strpgmexp pgmlvl(*prv) signature('version 02 24012017')
        export symbol...
        endpgmexp

        STRPGMEXP PGMLVL(*PRV) SIGNATURE('version 01')
        export symbol...
        endpgmexp

        Creating the service program results in a random signature instead of 'version_04_28092017'

        I found that All 4 blocks have procedures that do not actually exist. And the current block has procedures missing.
        I tried removing the 3 *PRV blocks entirely, commenting out the non-existing procedures from the current block, and adding the missing procedures into the current block.
        But that did not fix it, when I recreated the service program it still was using the exact same random signature instead of 'version_04_28092017'


        Then I tried replacing the binding source entirely with one generated using RTVBNDSRC. I updated its signature, so it's header line was:

        STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('20171120')

        One current block, no previous blocks, exactly matching what the service program is exporting

        But that still did not fix it, when I recreated the service program it still was using the exact same random signature.

        It seems to me that no matter what I do, CRTSRVPGM is ignoring the binding source

        Comment


        • #5
          And just like that, I stumbled onto the solution. The EXPORT parameter on CRTSRVPGM was set to *ALL instead of *SRCFILE
          Changed it to *SRCFILE and it now respects the binding source.

          Comment


          • #6
            Ah yes, you definitely don't want to use EXPORT(*ALL) or you won't be taking advantage of using binder source, as you've found out.

            I always create my service programs CRTSRVPGM just once in the beginning, and then always UPDSRVPGM for every subsequent addition/change. Quick and easy and never have to recompile things unnecessarily. Love it!

            Comment

            Working...
            X