× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



First of all, Brian is correct, since you listed the modules in the
binding directory, your program was created with a copy of the modules.
All the procedures were called from that copy; not from the service
program.

When you updated the service program you didn't affect the modules that
were copied into the program object.

You could have run the UPGPGM command to get your program to reference
the new modules, but this doesn't fix the issue with you referencing the
modules instead of the service program from the binding directory.


Here is my current understanding of service programs. Please, anyone,
feel free to set me straight if I am mistaken.

When you run CRTSRVPGM the service program is created with a copy of all
the modules that were included.

After that, you can change any module without effecting the service
program. i.e. no new changes to the module are reflected in the service
program. This is the same with creating ILE programs, once the program
is created you no longer need the module object other than to recompile
the program.

The only way to get the changes to the module to be reflected in the
service program is to run a CRTSRVPGM or an UPDSRVPGM.

The UPDSRVPGM will create a replacement object so that users that are
still active will be able to continue to reference the old version of
the service program.
The CRTSRVPGM has an parameter REPLACE which allows you to choose when
to create a replacement object. (Choosing "No" on replace causes the
create command to fail.)

After a service program is updated or created you no longer need the
modules on the production server.

The binding directory should contain the service program not the
modules.

The real trick with service programs comes with how you setup the Export
Source File used on the create and update commands
Specifically the export file's STRPGMEXP /ENDPGMEXP groups and their
associated SIGNATURE entries.

In our shop, we always provide a specific text signature. Some
arbitrary like "V1R1M0".
You should never change the order of EXPORT entries unless you want to
be required to recompile EVERY program that uses the service program.

If you must change the order, and there is no way around it, then you
should create a new STRPGMEXP /ENDPGMEXP group with a new unique text
signature and change the old group to PGMLVL(*PRV).

There should only be one STRPGMEXP /ENDPGMEXP group with
PGMLVL(*CURRENT), all old groups should have PGMLVL(*PRV ).

When a program is compiled it will always reference the "Current" group
to determine procedure exports.
Old programs continue to function because they reference a specific
signature from an older (*prv) export group that is still found within
the Exported signatures.

A compiled program initially looks up imported procedures by "Name" from
the CURRENT group. However, after that they are referenced by "Position"
within the signature's export list. This is why it's important not to
change the order of exports and always add new procedures to the end of
the list.

It is easiest to maintain one list of exports and always add new
procedures to the end of that list.

Each procedure also has a specific prototype that is used at creation
time. If you change a procedure's prototype then you must recompile all
programs that use that procedure.

There is a way around this issue. Say you have a procedure named
"GetName(INT)". You want to change it to "GetName(VARCHAR,INT)".
You want your old programs to continue to run, but they are using
"GetName(INT)". What you do is create the procedure
"GetName_Deprecated(INT)". And have the procedure call the new GetName.
Then, in all of the existing export lists you change the current
"GetName" to "GetName_Deprecated". Then you add the new "GetName" to the
end of the Current group.

This will allow new programs to use the "GetName(VARCHAR,INT)" and old
programs to continue and use "GetName(INT)".

As long as the old programs are not recompiled they will continue to
function by calling GetName_Deprecated whenever they were originally
calling GetName.
If you need to recompile one of the old programs you will have to modify
it to use the new version of GetName and pass the varchar instead of int
as parm 1.

Along these same lines, if you change the order of the exports you could
have a program calling the wrong procedure. Say you insert GetLastName
before GetName in your exports list, but don't change the signature and
don't recompile any programs. Once the service program is created or
updated all programs (that have not been recompiled) who were calling
GetName will now be calling GetLastName but think they are calling
GetName. This can cause really strange results if you don't realize what
is happening.

Chris Hiebert
Programmer/Analyst
Disclaimer: Any views or opinions presented are solely those of the
author and do not necessarily represent those of the company.

-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Koester, Michael
Sent: Thursday, October 04, 2012 10:30 AM
To: RPG400-L@xxxxxxxxxxxx
Subject: Troubles with UPDSRVPGM

Before I get too far into creating production objects without
understanding what I'm doing, I need help with something pretty
fundamental: Like how to update a module and not have to recompile the
world after doing so. Or at least knowing what steps ensure that the
new object will be used across the application.

I've created some RPG-ILE and SQLRPG modules, and created a service
program that "contains" them by listing each module in the MODULES
parameter on the CRTSRVPGM command. I created a binding directory that
lists each module. I then created a test program (with an H-spec
specifying the BNDDIR) to call a few of those modules. I compiled and
tested the test program. So far so good.
I modified some logic (without changing the interface) in one of the
called modules, recreated the module object, and saw that the module was
updated in the BNDDIR. I used UPDSRVPGM to get that change registered
in the service program. I signed off my session that I was testing in
(per suggestions from midrange archives), and signed back on to verify
that the changes would appear when I ran my test program.
The test program appears to use the former copy of the module.
I've been very deliberate about putting all the objects in the same
library, and restricting my library lists, so I think it's more a matter
of my not understanding what I need to do and how I need to do it.

If I recompile the test program, the new copy is called, but I was
hoping that wouldn't be necessary. I'm hoping to have these modules
available to many other programs without going through that. I've not
messed with binder language yet, but again, I haven't made any changes
to the interface.

Our CSM is home-grown (circa 1992) and knows nothing of ILE stuff. And
there's no chance of getting a commercial product to replace it here in
my lifetime.
OS is at 7.1

Thanks.
Michael Koester

--
This is the RPG programming on the IBM i / System i (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.