zur Homepage

Version 99 (final version?)

Diese Seite ist noch im Aufbau und wird fortlaufend erweitert, wobei ich durchaus zugeben muss, das das manchmal dauert. Vieles hiervon basiert auf Beiträgen von mir in Newsgroups, Foren, Mailinglisten und alles entstammt meiner täglichen Praxis.

Java auf der AS400

oder ist das überhaupt was besonderes?

Die folgenden Empfehlungen orientieren sich am Programmierstil, wie er in Java auf anderen Plattformen gepflegt wird. Zu den Zielen der Entwicklung von Software in Java gehört weniger Plattform Unabhängigkeit als universelle Wartbarkeit, Flexibilität und erst dann leichte Portierbarkeit. Die AS400 ist eine Nischenplattform, die wesentlichen Erkenntnisse im Software Engineering werden auf anderen Plattformen gemacht, mir geht es darum diese Erfahrungen auf der AS400 nutzbar zu machen.

Die Java Umgebung der AS400

Ist die AS400 eine Java Plattform?
Diese Frage ist von der Geschichte beantwortet worden: Nein! die AS/400 ist keine Java Plattform, aber Power Systems, genauer die p-Seite der Medaille, wie die AIX auch mal genannt wurde, ist eine Java Plattform. Die classic JVM ist tot, es lebe die J9. Damit könnte man diese FAQ eigentlich fast beenden, wenn da nicht noch all diese historischen Sonderlocken und der Mixbetrieb mit anderen Anwendungen wäre.

Java ist Ressourcen intensiv und benötigt in erster Linie Mega Hertz an Prozessorleistung und GigaByte an Hauptspeicher und das multipliziert sich mit der Anzahl der JVMs, die man parallel betreiben will. Batch und Interaktive Leistung und CPW sind Java auch auf der AS400 ziemlich egal, was zählt sind schnelle Prozessoren der neuesten Baureihen.

Java läuft nicht besonders schnell auf einer AS400, auf kleineren Maschinen sollte man eher Enttäuschungen mit einkalkulieren; durch die große Skalierbarkeit der Plattform wird es dann im Highend auch schnell - die Stärke der AS400 liegt aber eher in ihrer Gutmütigkeit, die zuweilen mit einer gewissen Behäbigkeit einhergeht.

Java auf der AS400, ist das was Besonderes?
Die Aufregung hierüber hat sich entscheidend gelegt, von WebSphere redet kaum noch jemand (Sagen Sie mal, ist das eine Komponente von Lotus Notes?), hier haben längst Tomcat, Apache, JBoss und Co. Einzug gehalten, und das ist auch gut so! Technisch ist die AS/400 eine reine Server Java Maschine, Client bezogene Komponenten sind nicht installiert, wer das haben will muss auf X-Windows auf der AS warten (könnte länger dauern). Wer es genauer wissen will, liest dieses Kapitel weiter, wem das reicht, der überspringt den Rest ds Kapitels. Java unterscheidet zwischen den Packages, die mit java anfangen und den Erweiterungen, deren Package Namen mit javax anfangen. Alles was zum Standard gehört, also alle Packages java.*, muss auf einer Java Plattform installiert werden; Teilinstallationen sind nicht zulässig. An dieser Stelle verfügt die AS400 bereits über die erste Besonderheit, die Packages java.awt.* sind als sogenanntes remote AWT implementiert, da die AS400 über keine Grafik fähigen Terminals verfügt. AWT Klasssen lassen sich in einer AS400 JVM nur ausführen, wenn eine sogenannte AWT Konsole konfiguriert ist. Die Klasse wird dann in der JVM der AWT Konsole ausgeführt und die Kommunikation zwischen den beiden JVMs erfolgt basierend auf RMI und Sockets Communication. Dieser Workaround war erforderlich, um Java auf der AS400 installieren zu dürfen. Für reale Anwendungsprogramme ist dieser Work around nicht wirklich zu verwenden.

Die neueren Grafik Komponenten, die heute für Clients bevorzugt werden, sind im Package javax.swing enthalten und gehören damit zu den Erweiterungen, die auf der AS400 nicht implementiert ist. Die AS400 ist also eine typische Java Server Maschine und als Client nur eingeschränkt verwendbar.

Die wichtigsten anderen javax Packages gehören vorwiegend in die Ecke Server Java und werden zumeist durch die Installation eines Application Servers auf die AS400 gebracht. Die meisten Application Server sind Java Anwendungen und lassen sich somit auf der AS400 installieren; es gibt also durchaus Alternativen zu WebSphere, der als AS400 Lizenzprodukt auf die AS400 kommt. Manche Bestandteile von Java, wie zum Beispiel die XML Parser, sind auch als separate Packages im Web verfügbar - oft als Open Source und Freeware.

Die Sache Remote AWT hört sich zunächst ein wenig exotisch, aber harmlos an - ist es aber durchaus nicht: zum Package AWT gehören nicht nur die Mäuse und die Fenster, sondern auch die Druck Unterstützung, die es mithin auf der AS400 nicht gibt! Dafür empfiehlt IBM dann seine Toolbox für Java auf der AS400, dazu wird noch einiges zu bemerken sein!

Die Java Runtime der AS400
Nachdem mit V5R4 da mehr oder weniger lautlos noch die 32 Bit JVM hinzugekommen war, die in vielerlei Kontext schneller als die 64 Bit Version ist; IBM hält sich da ein wenig bedeckt, es ist aber zu vermuten, dass die Original JVM von der AIX (neudeutsch p) in einer Art interner Pase Umgebung ist; installieren muss man selbige jedenfalls nicht zusätzlich. Unter V6R1 erscheint mir die AS/400 immermehr ein Gastbetriebssystem einer RS6000 zu sein, neben der 32 Bit JVM nähert sich die 64 Bit JVM auch immer mehr der p Variante an, zumindest wenn man der Doku glauben schenken will. Die einzelnen Java Runtimes werden jetzt auch analog zum Standard über Umgebungsvariable JAVA_HOME angesteuert; die Details hierzu findet man in der Doku des JDK für die AS/400.

Der ganze JVA Zinnober hat mit V7R1 ausgedient, was gebleiben ist, sind die unsäglichen Empfehlungen bezüglich EXTDIR und andere nicht Java gemäßen Ausführungen, aber die kann man jetzt alle getrost überblättern; wo wir gearde beim Thema sind: Das Java Kapitel im neuen Modernisation Redbook, einfach nur peinlich! Wer natürlich auf all diesen Unfug reingefallen ist, könnte beim Release Wechsel Überraschungen erleben, von nicht vorhandenen (adopted) Berechtigungen über RPG recompiles mit korrektem storage modell bis hin zu nicht gefundenen classes im vormaligen Extdir...

Java auf der AS400 als Standard Umgebung
Der Runde muss jetzt zwar ins Eckige, aber auf der AS/400 hat die JVA ausgespielt, da muss keiner mehr vor dem Knast Angst haben. Rudiment sind die beiden funktional identischen Befehle JAVA und RUNJVA , die man zum Glück nicht verwenden muss.

Wenn man in einer OS400 Befehlszeile unvermittelt QSH oder STRQSH eintippt, dann landet man in einer anderen Welt, die für OS400 Kenner zumeist fremd ist und für manchen dem OS400 fremd ist, vertraut sein könnte. Was man jetzt vor sich hat, ist ein magerer, aber immerhin Unix prompt. Man könnte jetzt mit Herbert G. fragen: Was soll das?, aber was in diesem Zusammenhang interessiert, ist dass diese Unix Befehlszeile Java kann, von javac über jar bis java und dabei alle Parameter versteht, so wie sie eine jede Unix Befehlszeile eben versteht. Was mir an dem QSH Befehl am besten gefällt ist, dass man im Parameter CMD gleich einen Befehl für die Qshell mitgeben darf und das ist genau das, was ich bevorzuge, wenn ich aus einem OS400 Programm ein Java Programm starten will. Und hier lassen sich auch alle Einstellungen der Java Ablaufumgebung als Parameter für den Java Aufruf unterbringen und ich kann auf die mir eher suspekten Umgebungsvariablen verzichten.

Im übrigen bietet die Shell language auch eine interessante Variante sich das Classpath Gedöns beim Start einer Java Anwendung vom Hals zu halten. Damit habe ich den Startprozess von AppServer4RPG mitsamt seiner Anwendungen ArdGate und CommandGate entscheidend vereinfacht, kann man sich ansehen, ist Open Source.

Ist Java für die AS400 was besonderes?
Java Programme unterscheiden sich in zahlreicher Hinsicht von all dem an das man denkt, wenn man im AS400 Umfeld den Begriff Programm verwendet. Java Programme laufen nicht unter dem Standard Command Interpreter QCMD, sondern nur unter der Unix ähnlichen Qshell.
Java Programme laufen nicht in interaktiven Jobs, können also kein 5250.
Java Programme erzeugen meist sogenannte Batch immediate (BCI) Jobs.
Java Programme erfordern eine Multithreading fähige Ablaufumgebung; das Subsystem muss also mehrere Jobs zulassen und braucht ausreichend Activity level.
Java Programme sind Hauptspeicher intensiv.
Java Programme erfordern viel CPU Zeit.
Java Anwendungen können Daten cachen und so Lesezugriffe einsparen.
Java Programme laufen auch auf anderen Plattformen.

Diese spezifische Charakteristik erfordert eine hinreichende Trennung verschiedener Ablaufumgebungen, wenn die Ressourcen optimal genutzt werden sollen. Problemlos ist das immer dann, wenn man für jede Workload einen eigenen Rechner hat; sobald man Anwendungen mit sehr unterschiedlichen Anforderungen auf derselben Maschine laufen lässt, wird manches komplexer. Wer hier das Schlagwort Server Konsolidierung im Hinterkopf hat, der muss sich auch Gedanken darüber machen, dass man nicht nur weniger Rechner zu betreuen hat, sondern auch kompliziertere Abläufe steuern muss. Nach meiner Erfahrung ist es durchaus positiv seine ersten Java Erfahrungen nicht auf der AS400 zu machen und dann über Konsolidierung nachzudenken. Der Versuch den umgekehrten Weg zu gehen wird oft unternommen, hat aber meist mehr negative als positive Auswirkungen. Insbesondere sieht man solchen Java Anwendungen oft an, dass sie für eine AS400 entwickelt wurden, bis hin zu stammelnden Feldnamen, fehlender Modularisierung, alle Komponenten static und was sonst in einem Java Programm noch alles RPG like aussehen kann.

Saubere Trennungen sind durch clustering auf der AS400 relativ elegant abzubilden, wenn die Hardware die Voraussetzungen dafür nicht mitbringt, hat man sowieso keine typische Java fähige AS400. Lässt man die komplette Verarbeitung auf einer einheitlichen Maschine laufen, sollte man zumindest die Hauptspeicher Anforderungen über Speicherpools voneinander trennen und muss dann natürlich die automatische Balancierung über die Änderung des Systemwertes QPFRADJ abschalten.

Schreibt man Java Anwendungen für eine AS400 anders, als für andere Plattformen?
Kurz gesagt: Hoffentlich nicht! Wer diesen Versuch unternimmt, was nicht so selten ist, der geht einen Weg auf dem er alle bereits existierenden Räder nochmal erfindet - und meistens sind die dann auch noch eckig.

Java kennt Datenbanken und greift per JDBC auf Tabellen, Views, Procedures und Functions zu und mehr hat die AS400 hier auch nicht und mehr braucht man für neue Anwendungen kaum, allenfalls noch Streamfiles. Zu jedem AS400 spezifischen Schnörkel der Toolbox existiert eine Java Standard Alternative, die Leistungs fähiger ist als diese Sammlung von Work arounds, der mit Ausnahme des JDBC Treibers allenfalls nostalgischer Wert bescheinigt werden kann. Zum Stichwort Toolbox: an der sind alle Entwicklungen der letzten 10 Jahre spurlos vorbei gegangen; naja, dann ist sie wenigstens nicht schlechter geworden, könnte man meinen, aber meibne klare Empfehlung bleibt: nur verwenden, wo es keine greifbaren Alternativen gibt.

Das Grundproblem besteht nicht darin AS400 Spezifika in einer Java Anwendung abzubilden, sondern ist viel allgemeiner: es geht um die Einbindung vorhandener Komponenten und das anbieten neuer Komponenten unabhängig von der eingesetzten Technologie und dafür sind Lösungen zu suchen im Anwendungsdesign und die Technik liefert nicht Java und erst recht nicht RPG, sondern eher SQL CORBA, Web Services und andere Standards.

Die AS400 als Datenbankserver

Welchen Treiber soll man verwenden?
Für die AS400 gibt es zwei JDBC Treiber, den sogenannten native Treiber und den sogenannten Toolbox Treiber. Zum guten Ton gehört im Server Java und nur hier hat man die Qual der Wahl, der Einsatz eines Connection Pools. Hierbei und in den meisten Anwendungen ohne auch, wechselt man den Treiber per Einstellung in einer Property Datei, sodass man leicht ausprobieren kann, welche Wahl die Beste für die eigene Anwendung ist.

der native Treiber ist vom Typ 2 und läuft nur auf der AS400 und kann nur an die lokale Datenbank verbinden. Dieser Treiber ist Bestandteil des Java Developer Kits der AS400 und wird auch damit ausgeliefert. Diesem Treiber werden zuweilen Wunderdinge in Bezug auf die Performance nachgesagt, die sich nicht immer messtechnisch realisieren lassen. Momentan wird wesentlich häufiger von anderen Plattformen auf die AS400 zugegriffen als lokal, sodass dieser Treiber wesentlich seltener benutzt wird als der universellere Toolboxtreiber. Das hat in jedem Fall zur Folge, dass der Toolboxtreiber nach meinen Erfahrungen der ausgereiftere Treiber ist, für den Fehlerbehebungen auch schneller zu bekommen sind. Nach Messungen wird von mir auch beim Zugriff auf die lokale Datenbank oft der Toolboxtreiber bevorzugt.

Den Toolboxtreiber bekommt man als Bestandteil der AS400 Toolbox für Java, einem nicht separat Kosten pflichtigen Lizenzprogramm, oder in der Open Source Variante mit dem jtopen.jar (Mr. Google weiss wo). Die Open Source Variante ist in der Funktion umfassender und aktueller. Bei den Treiber Properties habe ich früher für den extended dynamic support plädiert, der geringfügige Vorteile durch das cachen von Zugriffsplänen in einem sogenannten SQL Package bringen kann. Seit bei einem fehlerhaften Stand des Treibers enorme Laufzeitprobleme genau mit diesem Feature aufgetreten sind, ist mir der Einsatz zu riskant und ich rate mittlerweile definitiv davon ab. Das Schadenspotential überschreitet jeden von mir beobachteten Nutzen bei weitem.

Wenn wir schon bei den Treiber Einstellungen sind, die sollte man immer am SQL Standard orientieren und alle AS400 Sonderlocken meiden; das betrifft Commit level, naming conventions und natürlich auch sowas wie LIBL. Für mich ein Anachronismus ersten Ranges, nicht nur in Java. Erst entscheidet man sich für eine Datenbank mit referentieller Integrität und allem Schnickschnack und dann programmiert man nach dem Muster seh mal zu wo du passende Dateien findest und gibt sich selbst damit zufrieden, dass eine halbe Buchung in die Testumgebung geschrieben wird und die andere Hälfte in die Echtumgebung (und sage da keiner: das ist noch nie passiert).

Ansonsten sei noch bemerkt, dass Performance Probleme beim Datenbankzugriff zumeist ihre Ursache im Datenbank- oder Anwendungsdesign haben. Da wehrt man sich immer noch auf breiter Front vehement gegen Normalisierung, RI constraints, selbst der Einsatz von Commit ist verpönt, dafür werden stored Procedures and selbst UDTFs empfohlen, getreu nach dem Motto: alles was man auf allen anderen Plattformen anders macht ist Hexenwerk und alles, was nicht portabel ist, ist clever. Eine der größten Unsitten ist die kaum auszurottende Unsitte Datenbank Verbindungen mit dem anfordernden Benutzer zu machen und dann Anzeigen Seitenweise zu füllen und alle SQL Ressourcen möglichst selber festzuhalten (naja, kennen wir ja von RPG, aber auch da ist das Murks!).

Die AS400 als Webserver

Ist die AS400 ein WebServer erster Wahl?
Zu WebSphere lohnt es sich ja nicht mehr viel zu schreiben, das scheint den Weg von Lotus Notes gegangen zu sein (bevor mir noch jemand sagen konnte, was LN eigentlich ist). Übrig geblieben ist von diesem Branding eigentlich nur noch RPG und COBOL - Realsatire nach der Art von IBM. Aber zu AS400 als Webserver sind neue Kandidaten aufgetaucht. In der AS/400 Community werden Wege empfohlen und gegangen, die auf anderen Plattformen längst als Irrwege erkannt worden sind, zuweilen wird auch noch auf Züge verspätet aufgesprungen, die bereits hinter der Weiche zum Abstellgleis am ausrollen sind. Ich beschränke mich hier nur einmal auf PHP zum schreiben von kaufmännischen Anwendungen und die vermeintliche Wiedergeburt von JavaScript, wobei mir zum Stichwort Wiedergeburt so kurz vor Ostern eine andere Wiedergeburt einfällt, deren Plausibilität mir ebenfalls nicht besonders groß zu sein scheint. Ein gewisses Verständnis habe ich für diesen Hang zu wackeligen Programmiersprachen schon, man ist es halt von RPG her gewohnt, ein gewisses Glücksgefühl zu erleben, wenn es trotzdem funktioniert. In einer klaren Programmiersprache zu programmieren kann ja jeder, die Kunst fängt beim Seiltanz ja auch erst ohne Netz an.

Integration von Java und RPG

Java und RPG, verträgt sich das?
Rein geschichtlich gesehen verhalten sich Java und C zueienander wie Großhirn und Stammhirn. Die JVM ist im Kern in C geschrieben und damit das einfach geht, gibt es eingebaute Schnittstellen Mechanismen zwischen C und Java. Zu Beginn von Java las man auch in jedem Lehrbuch die Empfehlung zeitkritische Funktionen in C zu schreiben und dann aus Java aufzurufen. Mittlerweile ist diese Empfehlung aus fast allen Büchern verschwunden. Einmal ist Java wesentlich schneller geworden, durch bessere Implementierung der Standard Klassen und zum anderen haben sich die Mix Anwendungen als schlecht wartbar erwiesen. Heute kommt niemand mehr, naja sagen wir lieber fast niemand, auf die Idee C Funktionen neu zu programmieren, um sie dann aus Java aufzurufen.

Mit RPG und COBOL400 sieht das noch ein wenig komplizierter aus, da kommen zu den bei C Java Mix auftretenden Problemen noch technische Probleme hinzu und der Programmierstil des typischen COBOL oder RPG Entwicklers unterscheidet sich doch ein wenig vom gängigen C-Stil und ist weit entfernt vom typischen Java Stil und Objekt orientiertem Denken. Technisch gesehen sind die Java und die RPG/COBOL Ablaufumgebung miteinander komplett inkompatibel. Java läuft nur in einem Multi-threaded Umfeld, das erfordert schon der sogenannte garbage Collector, RPG und COBOL haben dagegen eine runtime, die nicht threadsafe ist, also im Multithreaded Umfeld instabil wird (unpredictable results nennt man das dann in technical references). Den Java Effekt erkennt man daran, dass sogenannte BCI (Batch immediate) Jobs auftauchen, sobald Java die Bühne betritt, an den RPG/COBOL Effekten hat man rumgedoktort mit Compile Options, die das Problem aber auch nicht vollständig beheben.

Die technische Lösung besteht letztlich darin, dass man innerhalb desselben Jobs tunlichst nur Java oder nur RPG laufen lässt und dann gegebenen Falls asynchron über Queues miteinander kommuniziert. In RPG hat man den synchronen Aufruf von Java sogar in den Compiler eingebaut, der daraus JNI Aufrufe generiert; offenkundig eine Hardware Absatz fördernde Maßnahme von IBM. Hier wird in jedem Job, der solche Aufrufe macht eine eigene JVM gestartet, die beim Start in der Größenordnung sec. CPU zieht und im Betrieb in der Größenordnung 100 MB Speicher braucht: Da kann einiges zusammen kommen, wenn das flott gehen soll.

Wir können aber doch nicht alles neu schreiben, gehört zu den häufigen Argumenten, mit denen ich oft konfrontiert werde. Das erste, worüber man sich klar werden muss (unabhängig von Java) ist, dass es Software gibt, die nicht mit vertretbarem Aufwand gerettet werden kann: die läuft bis zum Ground Zero und dann muss völlig abgelöst werden. Wenn vorhandene Software modular aufgebaut ist, dann sehen die Voraussetzungen zur Modernisierung besser aus, dann gibt es natürlich Komponenten, zum Glück meist in der sogenannten Business Logic, die weiter verwendet werden können. Heute würde man solche Komponenten außerhalb des AS400/RPG Ghettos (dieser Ausdruck brachte mir mal eine gelbe Karte in einer Java Mailing Liste ein) als CORBA Komponenten, WebServices, oder als Message Driven Beans einbinden, alles Dinge für die im AS400 Umfeld keine standardisierten Lösungen als Middleware vorhanden sind. In vielen konkreten Fällen geht es aber auch eine Nummer kleiner und eine Handvoll Schnittstellen Funktionen reichen aus, um vorhandene Komponenten in Java einzubinden und Java Dienste für RPG und COBOL Anwendungen verfügbar zu machen.

Java ruft RPG auf
Beginnen wir mit dem einfacheren Fall, der meist im Mittelpunkt steht, bevor man mit der Java Programmierung anfängt. Hat man erst mal angefangen landet man meist sehr schnell an dem Punkt, wo man sich fragt: Warum soll ich aus Java eigentlich RPG aufrufen? was RPG kann, kann Java schon lange! was auch stimmt, außer für 5250, aber das will man ja meist nicht mehr, wenn man sich mit dem Gedanken an Java beschäftigt. Aber sei es wie es sei, Fragen, die häufig gestellt werden, müssen von einer FAQ beantwortet werden. Rein technisch gesehen gibt es mehrere Wege aus Java ILE (und auch OPM) Programme aufzurufen.

Aus der Sicht von Java ist für Übergänge zur nicht Java Welt für synchrone Aufrufe, die dann im Prozess der JVM laufen, das Java native Interface (JNI) vorgesehen. Für nicht Java Aufrufe bedeutet das, dass man eine Java Methode als native deklariert und dann generiert man sich beim Java Compile daraus einen C Prototypen, ILE Programmierern sollte das vielleicht was sagen, den man dann mit einer C Funktion implementieren muss. Rein theoretisch könnte man diesen C Prototypen dann auch in RPG implementieren, aber wer kann das schon (außer T*R und B*M und S*K) und wenn man es täte, dann scheitert das am Multithreading (ja, ich weiß, das es da Erweiterungen am ILE gibt... ab V6R1 hätte man da wirklich eine Chance, aber vorhandene RPG Programme haben an sowas nie gedacht!!!).

Java hat auch asynchrone Wege anzubieten, mehr als sich ein RPG Programmierer meist so vorstellt, aber alle scheitern letztlich daran, dass RPG keinen der gängigen Standards unterstützt und der übrigbleibende Möchtegern-Standard MQ-Series im AS400 Umfeld selten zu finden ist. Für Aufrufe von Java nach RPG wäre das ohnehin Overkill, da es da einfachere Wege gibt. Für die Einbindung von Komponenten verwendet man gemeinhin Enterprise Java Beans, WebServices oder CORBA, aber all dies ist in der Welt von RPG nicht vorgesehen und die zarten Pflänzchen, wo einige Enthusiasten versuchen RPG mit XML zu verknoten konnten mich bisher nicht überzeugen.

Die Java Toolbox, sprich das Projekt jt400, hat eine ProgrammCall Klasse anzubieten, aber je mehr ich micht mit dieser DollSchachtel beschäftige, umso weniger mag ich diese in Java gegossene RPG Denke. Die Verwendung eines proprietären Serverdienstes wäre noch zu vertreten, wenn wenigstens dieses PCML zu gebrauchen wäre. Als ich das erste Mal im CRTRPGMOD über den Parameter PGMINFO gestolpert bin, dachte ich zunächst warum sagt einem das keiner früher, was es hier für tolle Sachen gibt und habe erwartungsfroh *PCML da rein getippt, um mich während des Compiles meinem Kaffee widmen zu wollen, den ich sicher verschüttet hätte, wenn ich schneller zur Tasse Java gegriffen hätte: der Compile eines in Produktion befindlichen Moduls ist schnöde abgeschmiert. Entsetzen machte sich bei mir breit, eine Quelle, die sich nicht wandeln lässt und das Modul in Produktion und kein CVS weit und breit... es war nicht das Modul, PCML geht nur, wenn keine Rückgabe Parameter verwendet werden, oder eine integer zurück gegeben werden. Verwendbar ist das also ohne Probleme für OPM Programme und alte MS DOS Schinken, die einen ERRORLEVEL zurück geben (sowas gibts auch bei C). Da rate ich lieber von ab, eh jemand auf die Idee kommt, dass man kein ILE oder kastriertes ILE macht, damit das dann besser mit Java zusammen passt.

Ich habe mir das Beste (unter Blinden ist der Einäugige König) bis zum Schluss aufgehoben, übrig bleibt der Aufruf von stored Procedures über JDBC. Auf keiner anderen Plattform ist es so einfach jede vorhandene Komponente zur stored Procedure und damit auch aufrufbar über JDBC zu machen, wie auf einer AS/400 und nachedem DB2/400 nicht mehr UDB heißt, wird sich das auch nicht mehr ändern. Der JDBC Treiber übernimmt die Konvertierung der Parameter, JDBC kümmert sich um die Synchronisation, womit die RPG Programme alle in einem single threaded Umfeld laufen, in den Java Programmen gibt es keine Byte Arrays und alles, was man irgendwo reinschieben kann, kriegt man klaglos wieder raus. Man kann Connection Pools seiner Wahl verwenden, oder es lassen, wenn die RPG Komponenten nicht unter Amnesie leiden sollen und Statusinformationen aus der Historie ihrere Aufrufe brauchen. Es bleibt ein Haar in der Suppe: es wandert Funktion in die Datenbank, die dort normalerweise nix zu suchen hätte, aber solange man das kapselt und nicht der Versuchung unterliegt das zum Prinzip zu machen (naja, die Vertreter der Linie: soviel RPG wie möglich und so wenig Java wie es geht, lesen meine FAQ eher nicht, sondern bevorzugen die java400-l), halte ich das für vertretbar.

Ein paar Wermutstropfen muss ich am Ende dieses Unterkapitels doch noch los werden. Was die User defined Functions angeht, da fängt es bereits an zu hakeln, das lässt sich seltsamerweise nicht mit allen exportierten Procedures hinbekommen, die mögen das Schlüsselwort Value nicht und akzeptieren allenfalls CONS, was sich bei nähremen hinsehen dann sowieso als (hopefully) CONST entpuppt. Eine andere leidvolle Erfahrung habe ich mal in einem Projekt gemacht, in dem ich etliche APIs für Java verfügbar machen musste. In diesem Fall war das Deployment das Hindernis stored Procedures zu verwenden, da die Java Anwendung mitsamt den API Zugriffen locations transparent sein sollte (sprich: die sollte sich automatisch auf einem beliebigen Agent selber installieren können). Das hat mich dann letztlich doch bei Toolbox und ProgrammCall landen lassen und dann pro API ein paar Pords2Pojo Beans gekostet.

RPG ruft Java auf
Auf den ersten Blick braucht man das scheinbar nicht: wo sollen in einer RPG Welt die Java Komponenten herkommen? Schaut man genauer hin, dann ist es genau umgekehrt. Die meisten RPG Anwendungen enthalten kaum Komponenten und die paar Datums Verdreher, die gibt es in Java bereits; aber gerade in den Bereichen, wo sich RPG schwer tut, wie XML, WebServices, PDF generieren, um nur weniges zu nennen, gibt es freie Java Komponenten hoher Qualität. Einem ähnlichen Trugschluss sitzt man hier sehr leicht an anderer Stelle auf, fragt man Herrn Google, was ihm zum Thema Java RPG CALL einfällt, dann stößt man als erstes auf die RPG Reference und euphorische Zeitschriftenartikel über die Aufrufe eines Java HalloWorld aus RPG, in der RPG Reference findet man dann *JAVA und Konsorten und ein Rückblick zu Herrn Google weist auch den Weg zu java400-l, den enthusiastischen Vertretern von embedded Java in RPG. Selbst wenn dies mit freundlichen Antwortzeiten, vertretbarem Ressourcenverbrauch und hinreichender Stabilität gesegnet wäre (es mangelt an jedem von diesem), würde ich davon abraten. Die resultierenden Anwendungen sind weder RPG noch Java und nicht wartbar, das ist die direkte Produktion von Altlasten (ich höre schon das Gejammer: das ist historisch gewachsen...). Man könnte ganze Abhandlungen über die Unzulänglichkeiten schreiben, ich empfehle stattdessen sich erst die RPG Brille aufzusetzen und den RPG Teil der Beispiele in den Manuals, Artikeln und Beispielen anzusehen, dann die Brille wechseln und mit der Java Brille den Java Teil der Beispiele anzusehen. Sollte es Ihnen an Brillen mangeln, sie kennen sicher einen RPG Programmierer, der kein Java kann, der sich die RPG Programme ansieht und einen Java Programmierer, der kein RPG kann, der sich die Java Programme ansieht.

Da gibt es ja noch Java stored Procedures, aber die können nur static Methoden und die JVM ist noch weniger kontrollierbar, als bei den JNI Aufrufen, die der RPG Compiler aus den *JAVA Klamotten in RPG Quellen generiert. Auch das kann es aus meiner Sicht nicht sein. Zu den Varianten per QCMDEXEC eine Java Anwendung mit main aufzurufen und damit eine Dataarea zu füllen (vielleicht kommt man per Toolbox und ein paar Hilfs CLs sogar an den LDA dran), die man dann im RPG wieder ausliest, überlege ich mir mal einen Vortrag für die Informatiker Fassenacht der Lauschbacher Eiskaale vorzubereiten. Damit bliebe für dieses Kapitel eigentlich nur ein allgemeiner Teil über, was man nun alles programmieren muss, um einen eigenen Serverdienst zu schreiben, der Javadienste für RPG Programme bereitstellt. Das war mir zu wenig und deshalb fehlte der Teil Java2RPG RPG2Java auch bisher und man musste dann schon im deutschen AS/400 Forum suchen, wenn man meine Meinung dazu ansehen wollte.

Die Grundidee ist relativ einfach: man startet eine JVM, die man resident hält und lässt in dieser JVM einen Listener an einem Datenkanal auf Aufträge warten, die von RPG Programmen in den Kanal gestellt werden und auf Antwort eines Java Programms warten, dass die Anforderung verarbeitet und die Antwort kommuniziert. Variatioansmöglichkeiten gibt es viele und da ist dann doch einiges zu programmieren, ehe der erste Aufruf erfolgen kann. Wenn man das aus der Java Perspektive betrachtet, dann ist das ein Applikations Server, der für RPG Java Komponenten verfügbar macht. Ich will an dieser Stelle nicht alle Überlegungen diskutieren, warum ich für meinen Entwurf AppServer4RPG mich im einzelnen für oder gegen diese oder jene Variante entschieden habe, aber die Zielrichtung war von Anfang an so ein Teil als OpenSource Projekt aufzuziehen und damit es kein Rohrkrepierer wird, habe ich mit der realen Ankündigung gewartet bis das Teil als Beta vorliegt.

AppServer4RPG

Konzeption
Der Server ist als Framework konzipiert, sprich als erweiterbare Komponente. Zur Kommunikation werden DataQs benutzt an denen der Server wartet und Requests in einem eigenen Thread pro Request abarbeitet. Zum senden von Requests wird ein bereitgestelltes RPG Serviceprogramm eingebunden, das die gesamte Abwicklung mit dem Java Server eigenständig abwickelt. In der Übergabeschnittstelle muss ein eindeutiger EventName verwendet werden, der einen EventHandler identifiziert (wird in einer properties Datei konfiguriert. Zur Parameter Übergabe und Rückgabe werden Datenstrukturen verwendet, um das Ganze RPG nah zu halten. Zur Entkoppelung beider Welten werden die Datenstrukturen in Hybrid Objekten (sehen extern aus wie Java Beans und sind intern Datenstrukturen) gekapselt, die zur Zeit noch händisch programmiert werden müssen (das muss und soll sich ändern - Generierung? - XML und Reflection?). Hier habe ich mich bewusst gegen RFML (warum muss ich da eigentlich immer aufpassen, dass ich da nicht RTFM Language tippe?) entschieden. Bei Verwendung dieser Klassen besteht immer die Gefahr, dass die RPG Welt sich in Form von byte Arrays und irgendwelcher Konvertierungsklassen, die beim reinschmeißen alles akzeptieren und beim rausholen mit Exceptions zurück werfen, tief in die Java Applikation versprenkelt und Erfahrungen bei Reviews geben mir an dieser Stelle nur zu oft Recht.

Ach ja, finden tut man den Application Server für RPG auf meiner Homepage, oder auch auf SourceForge, wobei sich beides momentan noch nicht unterscheidet.

ArdGate als Beispiel für Java Integration in RPG
Seit August 2010 ist AppServer4RPG den Kinderschuhen entwachsen und kein technologisches Muster mehr, sondern Basis einer kompletten Anwendung. Mit der Implementierung von ArdGate, einer universellen Brücke von DB2/400 nach JDBC hat AppServer4RPG nicht nur ein paar Erweiterungen bekommen, sondern das PORDS2POJO Pattern ist ein wenig verfeinert worden und die DataQ Schicht ist generalisiert worden. die Daten werden in Pakete geteilt und in Segmenten transferiert. ArdGate hat im ersten Jahr circa 1000 Downloads gehabt und ist mittlerweile in mehreren Ländern im Einsatz, darunter USA, Niederlande, selbstredend bei uns und auch in Italien gibt es mehrere Installationen, dazu kommen dann noch die Installationen von denen ich keine Rückmeldung habe, was die Mehrheit sein dürfte.

ArdGate ist in mehrerlei Hinsicht interessant, es ist Open Source und steht in Konkurrenz zu Produkten, die zig-Tausende kosten und kann dabei mehr als die meisten alternativen Lösungen. Gerade diese Alleinstellungs Merkmale hindern die Verbreitung eher und begrenzen ArdGate zum Geheimtip, der in Foren und Publikationen eher totgeschwiegen wird. Mittels ArdGate kann man von allen SQL Interfaces der AS/400 auf alle JDBC fähigen Datenbanken zugreifen, Satzweise, in Echtzeit, mit minimiertem Ressourcenverbrauch. Die Daten, die mit DB2 ausgetauscht werden sind recht wirr strukturiert und ließen sich nicht mit PCML beschreiben, wenn man das denn wollte. Die native Schicht ist in RPG implementiert und minimal schmal; die Applikation ist fast komplett in Java geschrieben, aus Aufwandsgründen, da die Programmierer Produktivität in Java ungleich größer ist.

Last not least sei noch erwähnt, dass ArdGate auch den Oracle Access Manager ersetzen kann, der unter V7R1 nicht mehr läuft. Es kann nicht nur, es tut auch, teils sogar ohne nennenswerte Anpassungen der RPG Anwendungen, die vorher über das Oracle Tool auf die gleichnamige Datenbank zugegriffen haben. Es gab aber auch Fälle, wo aus den Applikationen ein paar Nachlässigkeiten ausgebaut werden mussten, die das Oracle Tool wohl hinter den Kulissen ausgebügelt hat - Oracle ist halt wesentlich empfindlicher mit herrenlosen Ressourcen wie nicht geschlossenen ResultSets oder Statements und das hat sogar einen Namen: ORA-01000 ist manchen JDBC Anwendern ein Grauen...

CommandGate als Beispiel für die Leistungsfähigkeit von AppServer4RPG
In meiner News Section ist noch eine andere Story ausführlicher beschrieben, die ich hier nur kurz als Resultat wiedergeben. Portierung einer Java JNI Lösung (da fällt mir immer Gummilösung ein) nach AppServer4RPG brachte eine Verbesserung der Laufzeit um den Faktor 10 oder so ein, bei wesentlich verbesserter Stabilität (konnte man beim RPG-JNI Pendant eigentlich nicht so nennen) und nahezu unbegrenzter Skalierbarkeit. Als eher fauler Mensch, der insbesonder Routine Arbeiten hasst, habe ich das dann gleich generisch gelöst und Open Source gemacht.

Wie beginnen mit Java?

Java for RPG Programmers?
Vor das programmieren in einer neuen Programmiersprache haben die Götter, soweit man daran glaubt, das lernen gesetzt. Java hat nicht nur eine völlig andere Syntax als RPG, die ist eher C ähnlich, sondern Java ist eine Objekt orientierte Sprache, im Gegensatz zum prozeduralen RPG. Ohne Objekt orientiertes Design ist ein Umstieg von einer prozedurealen Sprache völlig sinnlos und bietet keinerlei Vorteil. Java ist nicht besser weil es anders ist, sondern Objekt Orientierung bietet die Möglichkeit für wesentlich höhere Wiederverwendbarkeit als prozedurale Programmierung. Welche OO Sprache man dann wählt, das ist völlig sekundär. Auf einer AS400 kommen da ohnehin nur Java und C++ in Frage, andere Compiler werden nicht angeboten. Beide Sprachen werden für alle Plattformen angeboten, was für Java spricht ist, dass es leicht zu erlernen ist, leichter als C++ allemal, auf Stabilität ausgerichtet ist und Technologien wie Web Entwicklung und Server seitige Komponenten unterstützt und einfach ermöglicht.

Im Zentrum des lernens muss von Beginn an die Entwicklung des Verständnisses für Objekt Orientierung stehen, sonst wird der Schritt zu einer Veränderung des Denkens in Richtung Objekt Orientierung gehemmt und nicht gefördert. Dies ist der wesentliche Grund dafür, dass alle Ansätze nach dem Motto Java für RPG Programmierer zum scheitern verurteilt sein müssen, so gut oder schlecht die Bücher und nicht zuletzt die Übersetzungen auch sein mögen. An derselben Krankheit leiden auch die abgeschwächten Versionen Java auf der AS400. Und hier liegt auch die Ursache dafür, dass alle Zauberer, soweit man überhaupt an diese glaubt, nicht weiterhelfen. Auch diese schaden eher, da hier Wiederverwendbarkeit durch Generierung ersetzt wird und das ist für den Anfang extrem schädlich und später zumindest fragwürdig.

Kann man Java im Selbst Studium lernen?
Das ist überhaupt keine Frage, wenn es eine Programmiersprache gibt, bei der das geht, dann ist es Java. Es gibt eine Vielzahl an Büchern und Tutorials, teilweise sogar in deutsch und vieles davon aus dem Web zum runterladen. Ich kann und will da keinen vollständigen Überblick geben und nur weniges als Richtung angeben. Sehr gut ist der Kurs von Hubert Partl (siehe auch meine Link Seite), den man sich kostenlos laden kann. Von den deutschsprachigen Resourcen das Beste, was ich für diesen Zweck kenne. Klar und sauber aufgebaut, Beispiele zum selber programmieren, auch für AS400 Programmierer einfach und verständlich. In englischer Sprache gefallen mir die Tutorials auf der Sun Seite am besten, diese bieten eine breite Palette auch an Spezialthemen, sind didaktisch hervorragend aufgebaut, lediglich in den Beispielen finde ich den zuerst erwähnten Kurs noch besser. Dafür sind diese Tutorials wieder stärker an Programmierern orientiert, die bereits Kenntnisse in einer anderen Sprache haben. Auf deutsch ist das Einstiegstutorial als Buch erschienen und stellt eine gute Wahl dar, für jene, die mit englisch ihre Probleme haben.

Zur Ergänzung und zum Nachschlagen eignet sich für Anfänger auch noch Bruce Eckels Thinking in Java, das allerdings ein wenig C lastig ist und Guido Krügers Java Buch, die beide im Web verfügbar sind (zumindest waren). Für Spezialthemen gibt es eine breite Palette von Tutorials mit stark streuender Qualität, zu den schwächeren zähle ich in diesem Bereich die Redbooks, die stark Produkt zentriert sind und bei denen der Anfänger nicht entscheiden kann, was davon Marketing ist, was funktioniert und dennen fast allen gemeinsam ein grauenhafter Java Stil ist.

Grundsätzlich gilt für Selbst Studium, dass es nicht jedermanns Sache und nur für die wenigsten der schnellste Weg zu Java ist. Einer der größten Nachteile ist, dass man keinen hat, den man fragen kann und oft fehlt es an ausreichender Selbstkritik oder Hartnäckigkeit. Zu den Vorteilen kann aber auch zählen, dass man sogar tiefer in Dinge reinarbeiten kann, wenn man denn von beidem genug hat. Ich jedenfalls, habe nie einen Java Kurs besucht.

Soll man einen speziellen Java Kurs für AS400 besuchen?
Wer schonmal in den Rest der Seite reingeschnuppert hat, der hat bereits gelesen, dass Java auf der AS400 nix völlig anderes ist, als auf anderen Rechnern: also kann man erstmal jeden beliebigen Kurs besuchen. Man sollte allerdings mit berücksichtigen, dass jeder Kurs auch seine spezifischen Adressaten hat und sorgfältig prüfen, ob die eigenen Voraussetzungen und die eigenen Erwartungen passen. Volkshochschulkurse richten sich zumeist an Nicht Programmierer und sind mehr darauf ausgerichtet, was man zu Beginn des Programmierens wissen muss und Java dient nur zur Illustration und als Beispiel. Java Kurse im Mainstream sind meist an Programmierer mit C und Unix Kenntnissen, oder an VB Programmierer adressiert, das kann für manchen RPG Programmierer eine Schwelle darstellen. Meiden sollte man Heizdeckenverkaufs Veranstaltungen wo in zwei Tagen ein kompletter Umstieg versprochen wird, da soll meist was völlig anderes verkauft werden.

Bei den Angeboten, die sich an Umsteiger richten, sind die auf C aufbauenden Kurse des Java Mainstreams für die meisten RPG/COBOL Entwickler weniger gut geeignet, hier werden einfach zu viel Syntax Komponenten vorausgesetzt. Bei den Spezialangeboten für die AS400 Klientel sollte man darauf achten, dass die Grundkenntnisse und Objekt Orientierung nicht zu schwach gewichtet sind. Für einen Grundkurs solte man eine Woche veranschlagen und sich als reiner Anfänger auf Grundlagen der Objekt Orientierung, Einstieg in die Sprache Java und allgemein verwendbare Komponenten konzentrieren, wichtig ist noch, dass ein ausreichendes Gewicht auf praktische Übungen gelegt wird und das Ganze nicht auf ein bestimmtes Werkzeug zentriert ist, egal welches das sein mag. In dieser Phase geht es darum die Sprache zu lernen und nicht darum ein meist viel zu komplexes Werkzeug zu verwenden.

Im zweiten Schritt geht die Reise dann für die meisten AS400 Programmierer in Richtung Server Programmierung, oder alternativ in Richtung Client Programmierung mit graphischen Frontends. Jetzt ist es wichtig auch damit anzufangen sich mit Anwendungsdesign zu befassen, wer dies nicht spätestens jetzt macht und auf quick and dirty setzt, der wird es sehr schwer haben jemals über dieses Stadium hinaus zu kommen, wer mit Ruck Zuck beginnt, landet fast immer bei Husch Pfusch (gilt übrigens nicht nur für Java). Bei der Auswahl von Kursen sollte man genau auf die Voraussetzungen und die angestrebten Ziele achten. Web Facing hat zum Beispiel mit Java nichts zu tun und wenn sich ein Kurs zu 80% mit einem Produkt befasst, dann sollte er zumindest kostenlos sein, egal ob es sich um einen Application Server oder eine Entwicklungsumgebung handelt. Eine Bemerkung am Rande noch: für die Verwendung der AS400 Toolbox braucht man keinen Kursus, wenn man halbwegs Java kann - da ist es vielleicht sinnvoller sich mit SQL oder JDBC zu beschäftigen. Solide SQL Kenntnisse (können auch von embedded SQL in RPG stammen) sind auch dann unumgänglich, wenn man später ein Framework wie Hibernate für den Datenbankzugrigff verwendet.

Jetzt habe ich Java gelernt, was nun?
Nach circa zwei Wochen Schulung, oder einem Äquivalent an Selbststudium hat man ein paar Grundbegriffe gelernt und jetzt bringt einen Theorie und Trockenschwimmen nicht mehr sehr viel weiter. Nun ist es an der Zeit für die ersten praktischen Erfahrungen. Entweder man kann jetzt in ein Projekt als Lehrling und Hilfskraft einsteigen, oder wenn es ein solches nicht gibt, weil man nur Lehrlinge und Hilfskräfte hat, dann geht vielleicht der umgekehrte Weg: man sucht sich einen erfahrenen Programmierer oder gar Meister als Unterstützung oder als Coach für ein Einstiegsprojekt. Für die Freelancer unter uns tut es hier vielleicht ein Praktikum, oder die Mitarbeit an einem Open Source Projekt, wiewohl es hier im AS400 Umfeld kaum was gibt und die Schwellenängste für was anderes beidseitig recht hoch sind. Für etablierte Projekte reicht das Wissen und Können jetzt ohnehin kaum.

Was immer man jetzt tut, ohne Praxis geht das ganze gelernte jetzt wieder flöten und es bleibt dann oft nur der Nutzen für seine Programmiertätigkeiten in der vorher ausgeübten Sprache, aber auch das kann den Aufwand wert sein.

Jetzt haben wir Java gelernt was nun?
Wenn man nicht als einzelner Java gelernt hat, sondern in einem ganzen Team in Java einsteigen will, dann braucht man jetzt personelle Verstärkung: entweder einen Java Programmierer mit Projekt Erfahrung und Design Kenntnissen, oder man macht jetzt mit Praxis zentrierten Workshops an einem realen Projekt weiter. Das Projekt sollte überschaubar sein und bereits die Technologien verwenden mit denen man später arbeiten will. Überschaubar heißt in diesem Stadium, dass es mit dem gesamten Team mit circa 3 bis 6 Wochen Aufwand in maximal einem Vierteljahr fertig gestellt werden kann. Die Komplexität sollte nicht zu groß sein, es sollten aber auch nicht zuviele Kompromisse gemacht werden und das Design sollte noch ausbaufähig sein. In jedem Fall sollte man hier keine zu großen Kompromisse machen.

Bei Web Anwendungen darf der Datenbankzugriff keinesfalls in den JSPs erfolgen, hier scheiden sowohl die SQL Tags der Standard Tag Libs und erst recht die wie sauer Bier offerierten IBM Data Access Beans aus, die sogar Visual Age überlebt haben und jetzt als dab Taglib traurige Wiedergeburt feiern. Ein rauf und runter programmieren der AS400 Toolbox bringt ebenfalls nicht weiter, ob es nun per Wizard oder zu Fuß erfolgt ist hier eigentlich egal.

5 bis 10 Browser Seiten als Java Server Pages; Model View Controller sollte das Design schon erkennen lassen, vieleicht ein kleines Servlet als eigener Controller, Struts ist in dieser Phase schon ehrgeizig, Datenbankzugriff per eigener Klassen, wenn es sich um maximal 3 Tabellen handelt, sind es mehr, dann darf es bereits Hibernate sein. Zum Kennenlernen der Arbeit mit Frameworks und Standard Komponenten bietet sich hier in jedem Fall log4J an, das braucht man sowieso.

Die Umgebung heißt doch WDSC, oder?
Die Antwort kann man wesentlich kürzen: Eclipse hat sich durchgesetzt: einfach das passende komplett Package für Standard Java oder J2EE in aktueller Version nehmen und gut ist. Läuft auf einem angegrauten Netbook dann schneller als die eher irrationale Variante auf einem High End PC.
Und was ist mit WebFacing?
Dazu schreibe ich liber nix, da gibt es wieder ein Redbbok (Modernisation) dazu und mir ist schon ganz flau im Magen, mit Java hat das ohnehin nix zu tun, oder sagen wir lieber fast nix!

zur Homepage