Sie sind nun wieder eingeladen, die Diskussion spezieller technischer Probleme mit zu verfolgen. Bitte schicken Sie Fragen, Anregungen oder Antworten zu den vorgestellten Themen – ebenso wie Ihre Kritik – an unsere e-Mail-Adressen: dieter.bender@MidrangeMagazin.de oder Redaktion@MidrangeMagazin.de Frage: Wir setzen die Technik des Beendens eines ILE-Programms mit der C-Funktion exit() aus dem Technik Forum ein. Es gibt aber Situationen, wo wir damit nicht ganz zufrieden sind. Bei einem Batch-Job, bekommen wir eine Meldung CPF1241 für reguläres Ende zurück. Wir hätten aber lieber eine CPF1240 für irreguläres Ende – ähnlich wie bei einem Compile im Batch. Geht das?
Antwort: Um mit Radio Eriwan zu beginnen: im Prinzip ja, aber nicht mit exit(). Für die Beendigungsnachricht eines Batch-Jobs wird der Errorlevel offenkundig nicht ausgewertet, aber mit einer etwas anderen Technik kann man das gewünschte Verhalten doch erreichen. Am universellsten geht das mit dem Auslösen einer Programmausnahme-Situation durch das Versenden einer Abbruchnachricht mit Hilfe des Systemprogramms QMHSNDPM. Für ein RPG-Programm verwendet man am vorteilhaftesten einen Prototyp; das vereinfacht die Verwendung des APIs und veranlasst den Compiler zur Überprüfung der Parameterschnittstelle. Die Angabe von CONST für die reinen Übergabeparameter ermöglicht die Verwendung von Literalen statt Variablen, was die Lesbarkeit der Programme an dieser Stelle fördert. Im PR Statement wird der Name des APIs durch den verständlicheren Namen SendSysMsg ersetzt.
Die Datenstruktur für die Fehlerparameter und die Basisdeklaration des Message Key-Parameters platziert man zusammen mit dem Prototyp in eine Copy-Strecke in einer Teildatei QMHSNDPM der Quelldatei QRPGLEH.
Die Einbettung in die /IF-Abfrage des Precompilers schützt zur Vermeidung von Übersetzungsfehlern vor doppeltem Einkopieren.
Die Verwendung von QMHSNDPM ist in allen Details in der Referenz der Message APIs beschrieben; eine komplette Beschreibung würde einen längeren Artikel benötigen und den Rahmen des Technik Forums sprengen. Deshalb werde ich mich auf die wesentlichsten Aspekte beschränken.
Zur komfortablen Verwendung des APIs wird dann der obige Prototyp benötigt, der mittels der Anweisung /COPY QRPGLEH, QMHSNDPM eingebunden wird. Der Aufruf ist in einem Programmausschnitt aus einem früheren Artikel zu sehen (das Programm dient zum generischen Compile von Programmen, gemäß Anweisungen in der Quelle und kann von der Freeware-Seite des Autors (www.bender-dv.de) geladen werden).
Im Beispiel wird eine allgemeine Abbruchnachricht an das aufrufende Programm gesendet, die signalisiert, dass der Compile nicht erfolgreich war – ganz analog zur Fragestellung. Als vorformulierte Nachricht wird CPF9898 aus der auf jedem System vorhandenen Nachrichtendatei QCPFMSG verwendet. Der Text der ersten Ebene wird als Parameter übergeben – im Beispiel: Compile not successfull. Der erläuternde Text ist bei der verwendeten Systemnachricht mit „Diese Nachricht wird von Anwendungsprogrammen als allgemeine Abbruchnachricht verwendet“ vorformuliert. Die Länge des Textes wird mit der Parameterangabe 25 weitergegeben; als Nachrichtentyp muss für unseren Zweck unbedingt *ESCAPE angegeben werden. Die nächsten beiden Parameter legen fest, an welcher Stelle im Aufrufstapel die Nachricht zuschlägt. Die Angabe *PGMBDY ist für ILE-Programme am komfortabelsten. Hierdurch wird festgelegt, dass der Programm-Einstiegspunkt als Referenz-Ort verwendet wird. Der nächste Parameter legt mit dem Wert „1“ fest, dass das aufrufende Programm die Nachricht bekommen wird. Die beiden letzten Parameter werden für unseren Zweck nicht ausgewertet und sind nur pro forma angegeben.
Wenn wir jetzt unser Programm CRTCPP mit SBMJOB TSTABNORM CMD(CALL CRTCPP PARM(…)) ausführen und in CRTCPP mit dem erklärten Mechanismus beenden, dann bekommt der Aufrufer mit der Systemmeldung CPF1240 und dem darin gesendeten Text „Abnormale Beendigung des Jobs 026798/BENDER/TSTABNORM“ den Abbruch des Batch-Jobs signalisiert.
In einem CL-Programm kann man denselben Effekt auch einfacher erreichen mit dem CL-Befehl: SNDPGMMSG.
Die Parameter werden ganz analog zur Verwendung des APIs belegt; lediglich wird hier *PRV statt Ziffer 1 verwendet und die Syntax ist ein wenig anders.
Die beschriebene Technik ist nicht auf den skizzierten Einsatz beschränkt, sondern ist generell die eleganteste Möglichkeit, dem jeweiligen aufrufenden Programm mitzuteilen, dass der Aufruf nicht erfolgreich war; sie wird im gesamten OS/400 als Mechanismus für die Programm-zu-Programm-Kommunikation eingesetzt. Der entscheidende Vorteil gegenüber häufig verwendeten Return Code-Parametern ist hierbei, dass das aufrufende Programm zur Fehlerbehandlung gezwungen wird und dafür im CL MONMSG und im RPG Errorextender (E) Bezugszahlen, ILE Conditionhandler und all die Mittel eingesetzt werden können, die für Fehlerbehandlung eingebaut sind. Und schließlich ist dies auch stilistisch ein winziger Schritt Richtung Java; hier würde man in solchen Fällen mit throw eine Exception werfen.
Den Autor Dieter Bender erreichen Sie unter dieter.bender@midrangemagazin.de