In den letzten Artikeln wurden IBM Services gezeigt, mit denen man die in (Service-)Programmen gebundene Module) sowie die verwendeten Service-Programme analysieren konnte. Mit weiteren IBM Services konnten die Daten-Exporte und exportierte Prozeduren ermittelt werden. Jetzt geht es auch noch darum über die eigentlichen Programme und Service-Programme detaillierte Informationen zu bekommen. Diese Informationen liefert der IBM Service PROGRAM_INFO. In diesem Artikel wird gezeigt welche Informationen geliefert werden und wie diese ausgewertet werden können.
Um Programme- und Service-Programme (wieder) korrekt erstellen zu können, sind die Informationen ob und welche Module und Service-Programme gebunden sind oft nicht ausreichend. So ist es z.B. bei Service-Programmen auch wichtig, ob diese mit Bindersprache erstellt wurden und wenn ja in welcher Quelle die Informationen hinterlegt sind. Ebenso ist es wichtig zu wissen, mit welcher Aktivierungsgruppe die (Service-)Programme erstellt wurden (z.B. für Overrides oder Commitment Control deren Default-Scope Aktivierungsgruppe ist). Aber natürlich spielen auch andere Compile-Optionen eine Rolle.
… und wenn man dann auch noch gleich erfahren könnte, wieviele Module gebunden sind und wieviele Prozeduren exportiert wurden und welche Signaturen aus anderen Service-Programmen in die (Service-)Programm-Objekte eingebunden wurden, wäre das von immensem Vorteil.
Genau diese Informationen liefert der IBM Service PROGRAM_INFO.
PROGRAM_INFO – (Service-)Programm Informationen
Der Service PROGRAM_INFO liefert detaillierte Informationen über Programme und Service-Programme, einschließlich der Erstellungs-Optionen, der Anzahl an gebundenen Modulen, sowie bei Service-Programmen eine Liste der Signaturen. Für Service-Programme, die mit Bindersprache erstellt wurden wird u.a. die verwendete Binder-Quelle (inkl. Quellen-Bibliothek und Quellen-Datei) ausgegeben.
Der Service PROGRAM_INFO stellt nicht nur Informationen über ILE-(Service-)Programme sondern auch über (alte) OPM-Programme und SQL Routinen (Stored Procedures, User Defined Functions, User Defined Table Functions und Triggers) bereit.
Der Service PROGRAM_INFO vereint Informationen aus den folgenden CL-Befehlen und System-APIs:
- CL-Befehl DSPPGM Programm anzeigen
Detail-Informationen
- *BASIC Allgemeine Programm-Informationen
- *SIZE Größen-Beschränkungen für Programme
- CL-Befehl DSPSRVPGM Service-Program anzeigen
Detail-Informationen
- *SIZE Größen-Beschränkungen für Service-Programme
- *SIGNATURE Signaturen für Service-Programme
- System-API QCLRPGMI Ermitteln Programm-Informationen
- System-API QBNRSPGM Ermitteln Service-Programm-Informationen
Unter dem folgenden Link kann auf die Detail-Beschreibung von PROGRAM_INFO zugegriffen werden:
Wie auch bei den anderen Services gibt es sowohl eine Tabellen-Funktion PROGRAM_INFO als auch eine View. Und wie bei allen anderen Services gilt, wenn die Selektions-Kriterien mit den Parametern der Tabelle-Funktion übereinstimmen, sollte aus Performance-Gründen die Tabellen-Funktion bevorzugt werden. Bei der Tabellen-Funktion erfolgt die Selektierung innerhalb der Funktion. Bei der View (die i.Ü. auf der Tabellen-Funktion basiert) werden zunächst alle Daten ermittelt und im Anschluss selektiert.
Anmerkung: Abfragen über die View PROGRAM_INFO können sehr lange dauern, da ggf. die Daten von allen (gebundenen) Modulen in allen Bibliotheken durchsucht werden. Deshalb sollte zumindest die Bibliothek in der sich (Service-)Programme befinden in denen die Service-Programme verwendet wurden, selektiert werden.
Weder die Tabellen-Funktion noch die View PROGRAM_INFO liefert außer der Anzahl der gebundenen Module keine weiteren Modul-Informationen. Sollten Modul-Informationen benötigt werden, muss der Service PROGRAM_INFO mit dem Service BOUND_MODLE_INFO über die Programm-Bibliothek und den Programm-Namen verknüpft werden. Das gleiche gilt für Informationen über gebundene Service-Programme, die im dem IBM Service BOUND_SRVPGM_INFO hinterlegt sind.
In dem folgenden Beispiel werden die Service-Programm-Informationen für das Service-Programm DWSQLPRD in der Bibliothek DIRWEB angezeigt.
An dieser Stelle werden neben der Programm-Bibliothek (PROGRAM_LIBRARY) und dem Programm-Name (PROGRAM_NAME) auch die Beschreibung (TEXT_DESCRIPTION), der Erstellungszeitpunkt des (Service-)Programms (CREATE_TIMESTAMP), die Bibliothek (EXPORT_SOURCE_LIBRARY), die Datei (EXPORT_SOURCE_FILE) sowie die Teildateien (EXPORT_SOURCE_FILE_MEMBER) in denen die verwendete Bindersprache hinterlegt ist angezeigt. Außerdem wurde die Aktivierungsgruppe (ACTIVATION_GROUP), die Anzahl der gebundenen Module (MODULES), der Service-Programme (SERVICE_PROGRAMS) und der exportierten Prozeduren (PROCEDURE_EXPORTS) selektiert. Desweiteren wird die Anzahl der Signaturen (SIGNATURES) und eine Auflistung der verschiedenen Signaturen (EXPORT_SIGNATURES) ausgegeben.
Quelle: HauserBeispiel 1: Ermitteln (Service-)Programm-Informationen über Tabellen-Funktion PROGRAM_INFO
In dem folgenden Beipsiel wird für alle Service-Programme, die sich in der Bibliothek (PROGRAM_LIBRARY) DIRWEB befinden und die mit DW (PROGRAM_NAME LIKE ‘DW%‘) beginnen und bei denen es sich um keine SQL Routinen oder C-Programme (PROGRAM_ATTRIBUTE NOT LIKE ‘%CLE%‘) oder in die mehrere Module gebunden sind (PROGRAM_ATTRIBUTE IS NULL) die Anzahl der gebunenen Module (MODULES), die Anzahl der verwendeten Service-Programme (SERVICE_PROGRAMS), die Anzahl der exportierten Prozeduren (PROCEDURE_EXPORTS) und die Anzahl der Signaturen (SIGNATURES) ausgegeben. Zusätzlich wird eine Auflistung der verschiedenen exportierten Prozeduren im Hex-Format (EXPORT_SIGNATURES) ausgegeben.
Quelle: HauserBeispiel 2: Anzeige Anzahl Module, Service-Programme, exportierte Prozeduren und Signaturen pro (Service-)Program
In dem folgenden Beispiel werden alle Service-Programme in der Bibliothek DIRWEB ermittelt, die entweder mehrere Signaturen haben (SIGNATURES > 1) oder in die entweder mehrere Module gebunden sind (MODULES > 1). Neben der Programm-Bibliothek (PROGRAM_LIBRARY), dem Programm-Namen (PROGRAM_NAME), der Programm-Art (PROGRAM_TYPE – OPM oder ILE), dem Objekt-Type (OBJECT_TYPE – *PGM oder *SRVPGM) und der Teil-Datei-Art (PROGRM_ATTRIBUTE) wird auch die Anzahl der gebundenen Module (MODULES), die Anzahl der exportierten Prozeduren (PROCEDURE_EXPORTS), sowie die Anzahl der Signaturen (SIGNATURES) angezeigt. Ebenso wird eine Liste der verschiedenen Signaturen (EXPORT_SIGNATURES) ausgegeben.
Quelle: HauserBeispiel 3: Auflistung aller Programme mit mehr als einem Modul oder mehr als einer Signatur
Das Ergebnis zeigt, dass in den meisten Service-Programmen jeweils nur ein einziges Modul gebunden ist und nur einige wenige Service-Programme aus mehr als einem Modul bestehen. Unabhängig davon ob nur ein oder mehrere Module gebunden wurden, es werden in allen Service-Programmen Prozeduren aus anderen Service-Programmen aufgerufen und aus allen Service-Programmen werden Prozeduren exportiert.
Die beiden Service-Programme mit mehreren gebundenen Modulen haben jeweils nur eine einzige Signatur, während die Service-Programme mit einem einzigen Modul mehrere Signaturen haben. Vermutlich wurde hier die Signatur beim Hinzufügen von neuen Prozeduren jeweils automatisch ermittelt.
In ILE-Umgebungen, in denen zunächst Quellen geändert und im Anschluss Module erstellt werden müssen, bevor diese in Programme und/oder Service-Programme gebunden werden, und in denen Module außerdem in mehrere unterschiedliche (Service-)Programme gebunden werden können, ist es wichtig prüfen zu können, ob die einzelnen Objekte korrekt und komplett erstellt werden konnten.
In dem folgenden Beipsiel wird die View PROGRAM_INFO mit der View BOUND_MODULE_INFO über die Programm-Bibliothek (PROGRAM_LIBRARY), den Program-Namen (PROGRAM_NAME) den Objekt-Typen (OBJECT_TYPE) verknüpft, um sowohl auf die (Service-)Programm-Informationen als auch die Modul-Informationen zugreifen zu können. Es werden nur die Programme und Service-Programme in der Bibliothek DIRWEB geprüft.
Es werden nur die (Service-)Programme selektiert, deren Erstellungs-Datum (CREATE_TIMESTAMP) vor dem Erstellungsdatum des Modules(MODULE_CREATE_TIMESTAMP) oder vor dem letzen Änderungs-Datum der Quelle (SOURCE_CHANGE_TIMESTAMP) liegt. Außerdem werde alle (Service-)Programme selektiert, in denen mindestens ein Modul enthalten ist, dessen Erstellungs-Datum (MODULE_CREATE_TIMESTAMP) nach dem letzen Änderungs-Datum der entsprechenden Quelle (SOURCE_CHANGE_TIMESTAMP) liegt.
Idealerweise sollte die Abfrage keine Datensätze ausgeben. Wenn doch müssen die entsprechenden Module ggf. neu erstellt werden und im Anschluss die (Service-)Programme, in denen diese Module eingebunden sind neu gebunden bzw. das neuerstellte Modul ausgetauscht werden.
Quelle: HauserBeispiel 4: Ermitteln geänderte Quellen und/oder Module, die noch nicht in (Service) Programme gebunden wurden.
In gewachsenen Anwendungen wurden/werden die vorhandenen Programme vielfach erst nach und nach in ILE-Objekte konvertiert. Das hat zur Folge, dass man u.U. einem Mix aus gewachsenen OPM-Programmen und einer hochmodularen ILE-Umgebung gegenübersteht. Mit der folgenden Abfrage werden alle OPM-Programme, die sich in der Bibliothek DIRWEB befinden aufgelistet. Dabei werden die Programm-Bibliothek (PROGRAM_LIBRARY), der Program-Name (PROGRAM_NAME), der Programm_Type (PROGRAM_TYPE – OPM oder ILE), die Mindestanzahl an übergebenen Parametern (MINIMUM_NUMBER_PARMS), die maximale Anzahl an Parametern (MAXIMUM_NUMBER_PARMS) ausgegben.
Des weiteren wird die Quellen-Bibliothek (SOURCE_FILE_LIBRARY), Quellen-Datei (SOURCE_FILE) und die Quellen-Teildatei (SOURCE_FILE_MEMBER) sowie der Zeitpunkt der letzten Quellen-Änderung (SOURCE_FILE_CHANGE_TIMESTAMP) ausgegeben.
Quelle: HauserBeispiel 5: Auflistung aller OPM Programme in Bibliothek DIRWEB
Im Ergebis sieht man, dass es sich überwiegend um CLP-Programme und einige RPGIII-Programme handelt. Diese Programme sollten in absehbarer Zeit in ILE-Ojekte konvertiert werden. Bei CLP-Programmen ist das kein Problem, da lediglich die Teildatei-Art von CLP auf CLLE konvertiert und die Quelle neu umgewandelt werden muss. RPGIII-Programme sollten (z.B. mit CVTRPGSRC) nach RPGIV konvertiert, geprüft und im Anschluss umgewandelt werden.
Gerade wenn es z.B. um Überschreibungen (z.B. mit den CL-Befehlen OVRDBF – Überschreiben Datenbanken-Datei oder OVRPRTF – Überschreiben Durcker-Dateien) oder die Verarbeitung unter Commitment-Steuerung geht, spielt die Aktivierungsgruppe eine große Rolle. Sowohl die Defaults für den Override-Scope in den Überschreibungsbefehlen als auch der Default für den Commitment-Scope sind auf *ACTGRP gesetzt, d.h. die Überschreibungen bzw. die Regeln für COMMIT und ROLLBACK gelten nur innerhalb der gleichen Aktivierungsgruppe.
Aus diesem Grund wurde vielfach beschlossen ILE-Programme mit der Aktivierungsgruppe *CALLER zu erstellen. Damit hat man zwar keine Probleme mehr mit der Überschreibung, aber wenn ILE-Programme aus OPM-Programmen aufgerufen werden, werden die ILE-Programme in der Default-Aktivierungsgruppe ausgeführt.
Und was noch schlimmer ist, wenn aus den ILE-Programmen Prozeduren in Service-Programmen ausgeführt werden, die ebenfalls mit *CALLER erstellt wurden, werden auch die Service-Programme in der Default-Aktivierungsgruppe ausgeführt … und das kann fatale Folgen haben, spätestenfalls dann wenn Dateien geschlossen werden, oder wenn ein RCLRSC ausgeführt wird. In diesem Fall werden die Dateien geschlossen und können nicht mehr geöffnet werden. Die einzige Option ist den Job zu beenden.
Deshalb ist es wichtig zunächst einmal herauszufinden, welche (ILE-)Programme in der Default-Aktivierungsgruppe laufen. Service-Programme können nicht direkt in der Default-Aktivierungsgruppe erstellt werden, sondern lediglich mit der Aktivierungsgruppe *CALLER oder einer benannten Aktivierungsgruppe.
In dem folgenden Beispiel werden alle ILE-Programme aufgelistet, die sich wie OPM-Programme verhalten, da sie in der Default-Aktivierungstgruppe erstellt wurden.
Quelle: HauserBeispiel 6 : Programme in der Default-Activation-Group
Das Ergebnis zeigt eine Reihe von CLLE und RPGLE-Programmen, die beim Umwandeln mit CRTBNDCL oder CRTBNDRPG in der Default-Aktivierungsgruppe erstellt wurden. Diese Programme sollten mit einer anderen Aktivierungsgruppe neu erstellt werden. Am Besten mit einer benannten Aktivierungsgruppe, zumindest jedoch in einer der Default-Aktivierungsgruppen für ILE Programme, d.h. QILE wenn das Programm im Single Level Storage ausgeführt wird oder QILETS wenn das Programm im Tera-Space ausgeführt wird.
Damit bei der nächsten Umwandlung dann nicht wieder die Default-Werte gezogen werden, sollten die entsprechenden Informationen in den H-Bestimmungen/CTL-OPT bei den RPG-Programmen und mit dem Befehl DCLPRCOPT Verarbeitungsopt. deklarieren () in den CL-Programmen hinterlegt werden.
In dem folgenden Beispiel wird ermittelt wie viele Programme und Service-Programme in welchen Aktivierungsgruppen ausgeführt werden. Die ermittelten Daten werden auf Programm bzw. Service-Programm-Ebene aufsummiert. Ebenso wird eine Gesamt-Summe ausgegeben.
Quelle: HauserBeispiel 7: Programme und Service-Programme in Aktivierungsgruppen
Das Ergebnis zeigt, dass die meisten CLLE und RPGLE-Programme in der Aktivierungsgruppe QILE ausgeführt werden. Einige wenige Programme werden in einer benannten Aktivierungsgruppe ausgeführt. Leider wird immer noch ca. 10% der Programme in der Default-Aktivierungsgruppe ausgeführt.
Bei den Programmen mit dem Programm-Attribut CLE handelt es sich fast ausschließlich um SQL Stored Procedures, die (automatisch) mit Aktivierungsgruppe *CALLER erstellt werden.
Einige wenige C-Programme und CLLE Programme werden mit Aktivierungsgruppe *NEW erstellt. Die Service-Programme wurden alle mit dem Unterlassungswert, also Aktivierungsgruppe *CALLER erstellt. Soweit eine Übersicht über die über den IBM Service PROGRAM_INFO gelieferten Service-Programm und Programm-Informationen.
In dem nächsten Artikel werden wir uns dann mit dem IBM Service für Binder-Verzeichnisse beschäftigen.
Bis dahin schon einmal viel Spaß beim Analysieren Ihrer Programme und Service-Programme.
Die Autorin Birgitta Hauser schreibt regelmäßig für den MIDRANGE Deep Dive.
