Java mit IBM i verbinden: JDBC, JTOpen und flexible Exporte mit XML, XSLT, JSON, CSV & Markdown

Symbolisches Netzwerkbild für JDBC-Verbindungen zwischen Java und IBM i beziehungsweise Db2 for i.
Java kann IBM-i-Daten nicht nur lesen. Mit einem sauberen Extraktions- und Transformationsansatz lassen sich daraus XML, JSON, JSONL, CSV, HTML oder Markdown erzeugen.

Ein Praxisblick auf ein kleines historisches Beispielprojekt: Was zeus-access-400 gut zeigt, was man heute anders bauen würde – und warum IBM i für Java-Integration spannender ist, als viele denken.

Java und IBM i passen erstaunlich gut zusammen. Über JDBC und den JTOpen beziehungsweise IBM Toolbox for Java-Treiber können Java-Anwendungen auf Db2 for i zugreifen, SQL-Selektionen ausführen und Ergebnisse weiterverarbeiten. Das kleine Beispielprojekt zeus-access-400 ist heute kein aktiv gepflegtes Produktivwerkzeug mehr. Trotzdem zeigt es eine interessante Idee sehr anschaulich: Eine SQL-Selektion wird einmal ausgeführt, zunächst neutral als XML abgelegt und anschließend über XSLT in verschiedene Zielformate transformiert.

1. Kurzfassung

zeus-access-400 ist ein kleines Java-CLI-Beispiel, das Daten über JDBC aus einer IBM-i-Datenbank liest und in mehrere Formate exportiert. Der technische Kern ist bewusst einfach:

Schritt Aufgabe Technische Idee
1 Konfiguration laden Properties-Datei mit JDBC-URL, Benutzer, SQL, Exportpfad und Ausgabeformaten.
2 Datenbank verbinden JDBC-Verbindung über com.ibm.as400.access.AS400JDBCDriver.
3 SQL ausführen Konfigurierte SQL-Selektion liefert ein ResultSet.
4 Neutral exportieren Das ResultSet wird zunächst als XML geschrieben.
5 Transformieren XSLT erzeugt daraus HTML, JSON, JSONL, CSV oder Markdown.
Der eigentliche Lernwert: Das Projekt zeigt nicht nur „Java kann JDBC“. Es zeigt, wie man IBM-i-Daten in eine neutrale Zwischenstruktur bringt und daraus verschiedene Ausgabeformate erzeugt. Genau diese Entkopplung ist für Reporting, Dokumentation, Datenanalyse und Modernisierung spannend.

2. Einordnung: Ein historisches Projekt mit aktuellem Lernwert

zeus-access-400 ist kein aktiv gepflegtes Produktivwerkzeug mehr. Das Projekt bleibt aber interessant, weil es eine klare und bis heute brauchbare Architekturidee zeigt: Daten werden per Java und JDBC aus IBM i gelesen, in eine neutrale Zwischenstruktur gebracht und anschließend flexibel in verschiedene Zielformate transformiert.

Status-Hinweis: zeus-access-400 ist ein historisches Beispielprojekt. Für neue produktive Einsätze sollte man den Code nicht unverändert übernehmen. Als kompakter Einblick in JDBC-Zugriff, XML-Zwischenformat und XSLT-basierte Ausgabeformate ist das Projekt aber weiterhin sehr anschaulich.

Gerade kleine Projekte haben einen Vorteil: Man sieht die Idee ohne viel Framework-Nebel. In diesem Fall geht es um drei praktische Punkte:

  • Java kann über JDBC sauber mit Db2 for i auf IBM i kommunizieren.
  • SQL-Ergebnisse lassen sich neutralisieren, bevor sie in konkrete Zielformate geschrieben werden.
  • XSLT kann eine schlanke Transformationsschicht sein, wenn XML ohnehin als Zwischenformat verwendet wird.

3. Die Grundidee: einmal selektieren, mehrfach ausgeben

Viele Datenexporte entstehen aus einer einfachen Anforderung: „Ich brauche diese Daten mal eben als CSV.“ Kurz danach kommt: „Kann ich das auch als JSON bekommen?“ Danach: „Für die Doku bitte als Markdown.“ Und irgendwann: „Eine kleine HTML-Ansicht wäre auch praktisch.“

Die naive Lösung wäre, für jedes Format eigenen Java-Code zu schreiben. Das funktioniert, wird aber schnell unübersichtlich. zeus-access-400 geht einen anderen Weg:

Architekturidee: Die SQL-Abfrage wird nur einmal ausgeführt. Das Ergebnis wird zuerst in ein neutrales XML-Format gebracht. Alle weiteren Ausgabeformate entstehen anschließend per Transformation.

Das ist nicht für jeden Anwendungsfall perfekt, aber als Muster sehr lehrreich:

  • Die Datenbeschaffung bleibt von der Darstellung getrennt.
  • Neue Zielformate können über zusätzliche XSLT-Dateien ergänzt werden.
  • Das XML-Zwischenformat ist prüfbar, versionierbar und gut nachvollziehbar.
  • Das Konzept funktioniert lokal, auf Servern und grundsätzlich auch in IBM-i-nahen Umgebungen.

4. Architektur des Beispielprojekts

Das Projekt ist klein und dadurch gut lesbar. Es folgt keinem modernen Framework-Ansatz, sondern einer klassischen Java-CLI-Struktur.

Baustein Rolle im Projekt Einordnung
AppInitializer Startpunkt der Anwendung. Lädt die Properties-Datei, befüllt die zentrale Konfiguration und startet den Service.
Config Zentrale Konfiguration. Hält Treiber, URL, Benutzer, Passwort, SQL, Exportpfade und Ausgabeformate.
PropertiesLoader Konfigurationslader. Liest externe Konfiguration aus einer Datei.
DatabaseManager JDBC-Helfer. Lädt den Treiber, öffnet und schließt Verbindungen, erstellt Statements.
DatabaseController Orchestrierung. Verbindet Datenbankzugriff, XML-Export und Format-Transformation.
DatabaseService Service-Schicht. Kapselt den eigentlichen Exportprozess aus Sicht des Starters.
XmlExporter XML-Erzeugung. Wandelt ein JDBC-ResultSet in ein XML-Dokument.
XMLtransformer XSLT-Transformation. Wendet XSLT-Dateien auf das XML an und schreibt die Zielformate.
Schön an diesem Aufbau: Man erkennt die Verantwortlichkeiten sofort. Der Code ist nicht modern im Sinne von Spring Boot, Dependency Injection, Test-Suite, Secrets Handling oder Query Guards – aber als Lernpfad ist er angenehm direkt.

5. Datenfluss: SQL → ResultSet → XML → Zielformat

Der eigentliche Datenfluss ist simpel und genau deshalb gut erklärbar.

Konzeptueller Ablauf
application.properties
        │
        ▼
JDBC-Verbindung zu Db2 for i
        │
        ▼
SQL SELECT ausführen
        │
        ▼
JDBC ResultSet
        │
        ▼
XML-Zwischenformat
        │
        ├── XSLT → HTML
        ├── XSLT → JSON
        ├── XSLT → JSONL
        ├── XSLT → CSV
        └── XSLT → Markdown

Der spannende Punkt ist das XML-Zwischenformat. Es enthält nicht nur Werte, sondern kann auch Metainformationen tragen, etwa Spaltennamen und JDBC-Typen. Dadurch wird das Ergebnis nicht nur „Textausgabe“, sondern eine strukturierte Zwischenrepräsentation.

Vereinfachtes XML-Ergebnis
<export>
  <data>
    <property path="CUSTOMER_NO" type="CHAR">
      <value>0004711001</value>
    </property>
    <property path="ORDER_TOTAL" type="DECIMAL">
      <value>1234.56</value>
    </property>
  </data>
</export>
Wichtig bei großen Datenmengen: XML als Zwischenformat ist nicht automatisch die beste Lösung für jeden Export. Für kleine bis mittlere Datenmengen, Dokumentation und nachvollziehbare Transformationen ist es angenehm. Für Massendaten sollte man Streaming, Fetch Size, Speicherverbrauch und direkte Formate wie JSONL oder CSV bewusst prüfen.

6. Unterstützte Ausgabeformate

Das alte Projekt zeigt mehrere Zielformate. Genau das macht es als Beispiel interessant.

Format Typischer Nutzen Kommentar
XML Neutrales Zwischenformat, technische Weiterverarbeitung. Gut prüfbar und transformierbar, aber bei großen Datenmengen schnell voluminös.
HTML Schnelle Ansicht im Browser, einfache Reports. Praktisch für Fachbereich, QS oder technische Dokumentation.
JSON Webanwendungen, APIs, moderne Integrationen. Gut für strukturierte Übergabe, aber Typ- und Encoding-Fragen sauber klären.
JSONL Zeilenorientierte Verarbeitung, Logs, Pipelines. Besonders praktisch, wenn Datensätze einzeln verarbeitet werden sollen.
CSV Excel, BI-Import, einfache Datenweitergabe. Delimiter, Quotes, Encoding und Dezimaltrennzeichen klar definieren.
Markdown GitHub-/GitLab-Doku, technische Reports. Sehr schön für nachvollziehbare Entwicklerdokumentation.
Der eigentliche Trick: Das Projekt koppelt die SQL-Selektion nicht direkt an ein einzelnes Ausgabeformat. Dadurch wird aus „ich brauche mal schnell CSV“ ein kleiner Export-Baukasten.

7. Konfiguration und Start

Das historische Projekt arbeitet mit einer einfachen Properties-Datei. Das ist für ein Beispiel angenehm greifbar.

Historisches Properties-Beispiel
driver=com.ibm.as400.access.AS400JDBCDriver
databaseUrl=jdbc:as400://YOUR_SYSTEM;translate binary=true
username=YOUR_USER
password=YOUR_PASSWORD

xsltpath=./xslt
exportpath=./export

query=SELECT * FROM YOUR_LIB.YOUR_TABLE
exportFormats=html,json,jsonl,csv,md
Heute bitte besser: Zugangsdaten gehören nicht dauerhaft in Klartext in eine Properties-Datei. Für echte Umgebungen sind Environment-Variablen, Secret Stores, eingeschränkte Benutzerprofile, Read-only-Rechte und saubere Protokollierung deutlich besser.

Der Build erfolgt klassisch mit Maven:

Maven Build
mvn clean package

Start unter Windows:

Windows
java -cp "zeus-access-400-1.0-SNAPSHOT.jar;jt400.jar" de.zeus.hermes.AppInitializer application.properties

Start unter Linux, Unix oder IBM i PASE:

Linux / Unix / IBM i PASE
java -cp "zeus-access-400-1.0-SNAPSHOT.jar:jt400.jar" de.zeus.hermes.AppInitializer application.properties
Kleiner, aber klassischer Unterschied: Unter Windows trennt ein Semikolon die Classpath-Einträge. Unter Linux, Unix und IBM i PASE ist es ein Doppelpunkt.

8. Warum das gerade auf IBM i interessant ist

IBM i ist nicht nur ein „altes System mit grüner Oberfläche“. Auf vielen Systemen liegen hochrelevante Geschäftsdaten direkt in Db2 for i. Gleichzeitig gibt es oft Bedarf, diese Daten für moderne Zwecke verfügbar zu machen:

  • technische Dokumentation bestehender Tabellen und Views,
  • regelmäßige Datenexporte für Fachbereiche,
  • Vergleichsdaten für Modernisierungsprojekte,
  • JSON- oder CSV-Dateien für externe Systeme,
  • Markdown-Reports für Git-Repositories,
  • HTML-Auswertungen für schnelle Sichtprüfungen.
Gerade auf IBM i spannend: Viele Datenstrukturen sind stabil, wertvoll und fachlich gewachsen. Ein kontrollierter Java-Export kann helfen, diese Daten sichtbar zu machen, ohne sofort eine große API-, Web- oder Migrationsarchitektur bauen zu müssen.

Wichtig ist aber: Ein Export ist keine Modernisierung. Er kann eine Modernisierung vorbereiten, dokumentieren oder begleiten. Die eigentliche Architekturfrage bleibt: Welche Daten dürfen gelesen werden? Wer darf sie sehen? Wie werden sensible Felder behandelt? Wie wird die SQL-Selektion geprüft? Und wie wird sichergestellt, dass Ausgabeformate fachlich korrekt sind?

9. Grenzen des alten Ansatzes

Das Projekt ist bewusst klein und direkt gehalten. Genau das macht es als Lernbeispiel angenehm. Für produktionsnahe Nutzung fehlen aber einige Dinge, die man heute von einem sicheren IBM-i-Datenexport erwarten würde.

Bereich Alter Ansatz Heute sinnvoller
Java-Version Java-8-Kontext. Aktuelle LTS-Version, klare Runtime-Anforderungen und automatisierte Tests.
Zugangsdaten Konfiguration über Properties-Datei. Environment-Variablen, Secret Stores, eingeschränkte Benutzerprofile und maskierte Logs.
SQL-Ausführung Die konfigurierte Query wird direkt ausgeführt. Read-only Guard, nur SELECT/WITH, keine schreibenden Statements.
Ausführungssicherheit Einfacher CLI-Start. Dry-run als Standard und explizites --execute für echte Ausführung.
Nachvollziehbarkeit Einfache Logausgaben. Run Manifest mit Query, Zeitpunkten, Ausgabeformaten und Ergebnisdateien.
Große Datenmengen XML-orientierter Export. Streaming, Fetch Size, Speicherlimits und gezielte Formate wie JSONL oder CSV.
Encoding Grundsätzlich textbasierte Ausgabe. Explizite Tests für CCSID, Umlaute, Sonderzeichen, DBCS und Feldlängen.
Die Einordnung ist wichtig: Die Grenzen des Projekts schmälern nicht den Lernwert. Sie zeigen vielmehr, welche Fragen ein moderner Nachfolger beantworten muss, wenn aus einem Beispiel ein robustes Werkzeug werden soll.

10. Wie man es heute robuster bauen würde

Würde man das Konzept heute neu bauen, wäre die Richtung klar: CLI-first, sicherer Standardmodus, nachvollziehbare Ausführung, deterministische Exporte und möglichst wenig Magie.

  • Dry-run standardmäßig aktiv: Ohne explizites --execute wird keine Query ausgeführt.
  • Read-only Guard: Nur lesende SQL-Statements erlauben.
  • Secrets schützen: Keine Passwörter in Logs, Manifesten oder Shell-Historien.
  • Konfigurationsreihenfolge dokumentieren: CLI vor Environment vor Config vor Defaults.
  • Query-Quelle nachvollziehbar machen: CLI-Query, Query-Datei oder Properties-Wert eindeutig markieren.
  • Run Manifest schreiben: Was wurde wann mit welchen Formaten erzeugt?
  • Formate deterministisch ausgeben: Gleiche Eingabe, gleiche Ausgabe – wichtig für Tests und Diffs.
  • Tests für IBM-i-Spezialitäten: CCSID, Dezimalwerte, Datum/Zeit, führende Nullen, Nullwerte.
Meine klare Meinung: Für IBM-i-Datenexporte ist Sicherheit keine Zusatzfunktion. Sie ist Teil des Produktdesigns. Wer gegen Produktivdaten selektiert, braucht Read-only, Audit, Maskierung und nachvollziehbare Konfiguration von Anfang an.

11. Nachfolger: zeus-ibmi-extract-transform

Der moderne Nachfolger heißt zeus-ibmi-extract-transform. Dort wird die ursprüngliche Idee in eine robustere Richtung weitergeführt: read-only SQL-Extraktion aus Db2 for i, CLI-first, mehrere Ausgabeformate, Dry-run als Standard und ein vollständigeres Sicherheitsmodell.

Aspekt zeus-access-400 zeus-ibmi-extract-transform
Status Historisches Beispielprojekt. Aktueller Nachfolger / Modernisierungspfad.
Ziel JDBC-Selektion und Format-Export demonstrieren. Kontrollierte read-only Extraktion aus IBM i.
Ausführung Direkter Start mit Properties. Dry-run standardmäßig, echte Ausführung per --execute.
Sicherheit Einfaches Beispielniveau. Read-only Guard, Secret-Masking, definierte Konfigurationspriorität.
Formate XML, HTML, JSON, JSONL, CSV, Markdown über XSLT. Multi-Format-Export mit robusterem CLI- und Manifest-Konzept.
Audit Logs. Run Manifest zur Nachvollziehbarkeit.

Das Legacy-Projekt bleibt hier verlinkt, weil es die ursprüngliche Idee gut zeigt:
zeus-access-400 auf GitHub.
Für neue Entwicklung ist der Nachfolger die bessere Adresse:
zeus-ibmi-extract-transform auf GitHub.

12. Fazit

zeus-access-400 ist kein modernes Produktivtool mehr – aber ein gutes Beispiel für eine robuste Grundidee. Das Projekt zeigt kompakt, wie Java über JDBC mit IBM i sprechen kann, wie SQL-Ergebnisse neutral als XML abgelegt werden und wie daraus per XSLT verschiedene Zielformate entstehen.

Der eigentliche Wert liegt nicht darin, den alten Code unverändert weiterzuverwenden. Spannend ist das Muster dahinter: Datenbeschaffung und Ausgabeformat werden voneinander getrennt. Dadurch kann eine SQL-Abfrage Grundlage für HTML, JSON, JSONL, CSV oder Markdown werden.

Für heutige IBM-i-Projekte würde man Sicherheit, Konfiguration, Secrets, Read-only-Guards, Logging und große Datenmengen deutlich strenger behandeln. Die Architekturidee bleibt trotzdem stark: Erst sauber extrahieren, dann kontrolliert transformieren.

Weiterlesen in der Reihe: Für die Grundlagen von JDBC passt der Beitrag JDBC – Was ist das eigentlich?. Für Datentypen, Präzision, Unicode und typische Migrationsfallen lohnt sich zusätzlich IBM RPG und Java: Datentypen im Vergleich. Und für die größere Architekturperspektive passt IBM RPG und Java im Vergleich.

Glossar

Kurz erklärt – für alle, die zwischen Java-, JDBC-, XML- und IBM-i-Welt übersetzen müssen.

IBM i
Modernes IBM-Betriebssystem auf Power Systems. Wird umgangssprachlich oft noch AS/400 genannt, auch wenn das historisch nicht sauber ist.
Db2 for i
Die in IBM i integrierte relationale Datenbank. Sie kann klassisch über IBM-i-Mechanismen und modern per SQL/JDBC angesprochen werden.
JDBC
Java Database Connectivity. Java-API für Datenbankverbindungen, SQL-Ausführung und Verarbeitung von Ergebnissen.
JTOpen / IBM Toolbox for Java
Java-Bibliothek für die Integration mit IBM i. Enthält unter anderem den bekannten JDBC-Treiber com.ibm.as400.access.AS400JDBCDriver.
ResultSet
JDBC-Objekt, das das Ergebnis einer SQL-Abfrage zeilen- und spaltenweise bereitstellt.
XML
Strukturiertes Textformat. Im Beispielprojekt dient XML als neutrales Zwischenformat.
XSLT
Transformationssprache für XML. Damit können XML-Daten regelbasiert in andere Formate wie HTML, Text, CSV oder JSON-nahe Ausgaben überführt werden.
JSONL
JSON Lines. Zeilenorientiertes Format, bei dem jede Zeile ein eigenes JSON-Objekt enthält. Praktisch für Pipelines und große Datenströme.
Run Manifest
Protokolldatei eines Laufs. Sie dokumentiert, was ausgeführt wurde, welche Konfiguration galt und welche Ausgaben entstanden sind.

Quellen