Where Do Library Lists Reside?
August 4, 2015 Ted Holt
I often sit and ponder the mysteries of life. For example, why do some people use C to write business applications? Why does the text of message SQL6789 end in a period instead of a question mark? And, recently, why do people circumvent powerful features of the robust IBM i operating system? Let me show you what I mean.
The circumvented feature that is on my mind at present is the library list. In case you’re new to the IBM i world, the library list is a list of libraries that the system searches when looking for an object. It’s similar in concept to the path variables that are used in less robust operating systems, which are more or less a collection of utilities.
IBM i searches the library list for any type of object: programs, files, data areas, data queues, output queues, and so forth. This allows users to do their jobs without stepping all over each other’s feet.
For example, consider a manufacturer with factories in two cities: New Yolk and Lost Angeles. The users in both factories can share the same program library, but use separate data libraries.
The New Yolk users have a library list like this:
NYLIB PGMLIB QGPL QTEMP
Lost Angeles users have a library list like this:
LALIB PGMLIB QGPL QTEMP
Recent source code listings that I have seen have made me painfully aware that people often hard code library names rather than letting the system search the library list. I thought everyone had quit hard coding library names eons ago, but being my usual naive self, I was wrong.
Here’s an example that illustrates.
ADDLIBLE LIB(MYLIB) POSITION(*FIRST)
The programmer thought, “This program needs library MYLIB because that’s where file XYZ is. Since MYLIB is not in the library list, I’ll just add it.”
OVRDBF FILE(MYFILE) TOFILE(HISLIB/HISFILE)
Maybe HISLIB was not in the library list. Maybe HISLIB was in the library list, but another library higher in the list also had HISFILE. Who knows?
Here’s one more for good measure.
Maybe THEIRLIB is not in the library list. Maybe THEIRLIB is in the library list and the programmer qualified the program name anyway. I’ve seen it before.
Why is hard coding library names less than ideal? For one thing, it eliminates or at least obstructs the use of parallel databases, as in the New Yolk-Lost Angeles example. In one of the most convoluted examples of coding I’ve ever seen, CL programs retrieved a data area (using the library list), then read the contents of the data area to condition overrides.
DCL VAR(&LOCATION) TYPE(*CHAR) LEN(12) RTVDTAARA DTAARA(LOCATION *ALL) RTNVAR(&LOCATION) IF COND(&LOCATION *EQ 'Lost Angeles') THEN(DO) OVRDBF FILE(NYOPNORD) TOFILE(LALIB/LAOPNORD) ENDDO ELSE CMD(DO) OVRDBF FILE(NYOPNORD) TOFILE(NYLIB/NYOPNORD) ENDDO
I think most programs had “logic” like this, and it was certainly one of the most bizarre systems I ever worked on.
Hard coding library names also blows testing to smithereens. If you don’t hard code a library name, you can insert test libraries ahead of production libraries in order to test program changes. If a CALL has a hard coded production library name, the system won’t run your test version.
What’s the number one reason for hard coded library names? Heck if I know. But one big reason is that people don’t create job descriptions. They run everything through job descriptions that come with the system, such as QBATCH and QDFTJOBD. Job descriptions are still underused and unappreciated. These job descriptions are not designed for their environments and don’t have the required libraries.
Recently a fellow IBM i professional told me that he needed to make a program submit a batch job that needed a library that was not in the library list. Without knowing why, he knew that a batch job uses the library list of the submitter. I told him he had two choices.
One, he could modify the library list that the submitting job used. I assumed that would be a job description that pointed back to system value QUSRLIBL, but boy, was I wrong! The submitting interactive job, that is to say, the interactive jobs of the end users, ran an initial program with a lot of Add Library List Entry (ADDLIBLE) commands in it. (It was not the first time I had seen this technique used to set the library list of an interactive job.) Since the users did not need this library, he decided not to modify their initial program.
His other option was to create a job description for his batch job, list the required libraries in the batch job, and use INLLIBL(*JOBD) in the Submit Job (SBMJOB) command. Here’s the sort of thing I’m talking about.
SBMJOB CMD(CALL PGM(GL855C)) JOB(GLPOSTING) JOBD(GLPOSTING) JOBQ(*JOBD) INLLIBL(*JOBD)
He created a new job description. Problem solved, and easily at that.
So where do library lists reside? They reside in job descriptions. The reason is that there is no *LIBL object in IBM i is that there is no need for one.
One word of caution is in order. Before you delete or rename a library, be sure to remove it from any job descriptions where it is referenced, whether in the initial library list or some other parameter. If you think about it, the more you’ve hard coded a library name, the more work you must do before you can delete or rename the library.
As for those mysteries, I suppose some people write business applications in C because that’s the only language they know or the language they know best. It’s the same reason I write some of my utilities in RPG when I should probably use C instead. The bottom line is that you and I can’t control other people.
As for SQL6789, I’m sure that the person who wrote that message text knows that interrogative sentences end with a question mark. It’s just an oversight. I often make such mistakes, even in the articles I write for this august publication. Again, there’s nothing you or I can do about that message text.
As for circumventing the library list, I don’t know why IBM i programmers hard code library names so frequently, but I do know that this is something you and I can do something about, at least in our own shops.