Diesen Artikel habe ich ursprünglich im SAP Community Network veröffentlicht.
Vor einiger Zeit hatten Christian Drumm, Fred Verheul und ich eine „Twitter-Diskussion“, die Christian bereits im gestrigen Blog zusammengefasst hat Question: What System Landscapes Setup to use for Add On Development?. Während ich versuchte, eine für den Artikel geeignete Antwort zu finden, kamen mir immer mehr Details in den Sinn, sodass ich beschloss, die Diskussion mit einem oder zwei eigenen Blogs weiterzuverfolgen. Zunächst möchte ich mich dem Thema der fehlenden Branching-Unterstützung in ABAP widmen.
Die Unterstützung von Branches kann ziemlich knifflig sein, selbst wenn man nur den Quellcode und die zugehörigen Dateien betrachtet. Tatsächlich ist es nicht das Branching, das schwierig ist, sondern das Zusammenführen und die damit verbundenen Bereinigungsvorgänge, aber die meisten der damit verbundenen Probleme wurden entweder gelöst oder zumindest so weit automatisiert, dass die meisten Entwickler sie nutzen können. Naja, mehr oder weniger.

(xkcd #1597 by Randall Munroe, published under the Creative Commons Attribution-NonCommercial 2.5 License)
Bei einem durchschnittlichen Nicht-ABAP-Projekt wird der Code nicht direkt von einem Branch Ihres VCS/RCS ausgeführt. Zumindest müssen Sie den Code auschecken, ihn möglicherweise in eine Binärdatei kompilieren und erst dann lokal ausführen und/oder auf einem Server installieren. Dies gilt auch für Entwickler, die die Software ausführen – selbst wenn Sie nicht in Betracht ziehen, eine .war/.ear-Datei in der Produktionsumgebung bereitzustellen, benötigen Sie eine lokal ausgeführte Anwendungsserverinstanz, nur um die Anwendung auszuprobieren. Und anscheinend ist dieser Prozess in überraschend vielen Fällen eine echte Quelle der Freude oder so etwas sein.
Die ABAP-Umgebung unterscheidet sich in einigen Aspekten grundlegend:
Der Code wird aus demselben Repository kompiliert und ausgeführt, in dem er gespeichert ist. Es ist kein separater Kompilierungs- oder Schritt zur Bereitstellung erforderlich, bevor eine geänderte Version des Codes ausgeführt wird. (Die Aktivierung zählt in diesem Fall aus Gründen, die ich hier nicht näher erläutern möchte, nicht.) Da es keinen expliziten Kompilierungs-, Verknüpfungs- oder Bereitstellungsprozess gibt, müssen die Schritte, die normalerweise in einem solchen Prozess stattfinden, entweder zu einem anderen Zeitpunkt ausgeführt werden (was bei der Kompilierung von Lade-/Bytecode der Fall ist), oder sie finden überhaupt nicht statt. Das Linken von Binärdateien und das Auflösen von Bibliotheksreferenzen findet beispielsweise einfach nicht statt, weil ABAP kein Konzept hat, das einer Objektdatei oder einer gemeinsam genutzten Binärbibliothek ähnelt.
Der Code wird immer zentral ausgeführt, da keine lokale Ausführungsumgebung vorhanden ist. Die Unterstützung für die Entwicklung auf verschiedenen Code-Branches, die man erhält, wenn jeder Entwickler eine separate Laufzeitinstallation auf seinem lokalen Rechner hat, ist auf diese Weise nicht möglich – es müssten einige zusätzliche Vorkehrungen getroffen werden, um mehrere Versionen von ABAP-Programmen in einem System nebeneinander existieren zu lassen.
Stellen wir uns für einen Moment vor, es gäbe tatsächlich eine Möglichkeit, eine alternative Version, einen Branch, einer ABAP-Klasse zu erstellen und sowohl die Originalversion als auch die Branch-Version gleichzeitig verfügbar sind. Natürlich müssten Sie irgendwie auf die verschiedenen Versionen verweisen. In einem Nicht-ABAP-Projekt geschieht dies durch Auswahl der verschiedenen Zweige beim Auschecken der Arbeitskopie. Da Sie in ABAP nichts auschecken, benötigen wir einen anderen Ansatz. Das erste, was einem wahrscheinlich in den Sinn kommt, wäre, die Version anzugeben, wenn man sich auf die Klasse im Code bezieht. Das wäre eine schlechte Idee – nicht nur würde es den Code stark durcheinanderbringen, sondern auch das Wechseln zu einer neuen Version einer „Bibliothek“ zu einer mühsamen Aufgabe des Suchens und Ersetzens der Referenzen im Code machen. Wie wäre es also mit einer Art übergeordneter Gruppierung, z. B. „Paket ABC Version 2 erfordert Paket DEF Version 3“? Dieser Ansatz würde zwar die operative Handhabung der Beziehungen etwas erleichtern, aber an einem anderen grundlegenden Problem würde sich nichts ändern. Nehmen wir an, Ihr Paket erfordert derzeit zwei Frameworks A und B in Version 1, und Framework B Version 1 wiederum erfordert Framework A in Version 1. Nehmen wir nun an, dass es eine verbesserte Version 2 von Framework A gibt und der Entwickler von Framework B aus irgendeinem Grund beschließt, auf diese Version umzusteigen. Ohne eigenes Verschulden entsteht ein Konflikt: Sie benötigen Framework A Version 1 und Version 2 gleichzeitig – was nicht wirklich machbar ist. Willkommen in der Hölle der Abhängigkeiten. Es gibt Möglichkeiten, dieses Problem zu umgehen (schließlich kommt der Rest der Welt auch irgendwie zurecht), aber es fügt eine weitere Komplexitätsebene hinzu. Und leider haben wir gerade erst an der Oberfläche gekratzt.
Eine Aussage, die ich in Diskussionen über die Unterstützung von Verzweigungen für ABAP immer wiederhole, ist, dass man sich daran erinnern sollte, dass „ABAP viel mehr als nur Code ist“. Nehmen wir ein einfaches Beispiel: Eine Klasse hat eine Getter-Methode, die eine Beschreibung zurückgibt, und aus keinem bestimmten Grund ist diese Beschreibung ein 60-Zeichen-Textfeld, das mit einem Datenelement und einer Domäne eingegeben wird. Aus irgendeinem Grund wird entschieden, dass die Beschreibung Texte mit mehr als 60 Zeichen unterstützen muss, und da die Diskussion über das neue maximale Ende in naher Zukunft nicht zu einem Ergebnis zu kommen scheint, entscheiden Sie sich, den Rückgabetyp in eine nicht längenbeschränkte Zeichenfolge zu ändern, indem Sie die Domäne ändern oder ersetzen. Wenn Sie dies innerhalb einer Version tun würden, würden Sie wahrscheinlich einige Aufrufklassen beschädigen, da Sie nun eine unbeschränkte Zeichenfolge zurückgeben, wo diese nur ein Zeichenfeld mit fester Länge erwarten. Daher erstellen Sie eine neue Version Ihres Pakets und stellen sicher, dass Sie alle Anwendungsfälle des gerade geänderten Getter abdecken. Allerdings ist Ihnen möglicherweise entgangen, dass dieses bestimmte Datenelement auch in einer Datenstruktur verwendet wurde. Auch wenn Sie diese Datenstruktur nicht berührt haben, haben Sie sie implizit geändert, indem Sie eines der enthaltenen Datenelemente geändert haben. Das System müsste diese Situation also durch einen komplizierten Mechanismus erkennen und auch eine neue Version der Datenstruktur erstellen. Möglich, aber komplex und wahrscheinlich ziemlich kostspielig.
Gehen wir nun noch einen Schritt weiter und nehmen an, dass die Struktur in einer transparenten Datenbanktabelle enthalten war – und Sie sehen sofort, wohin das führt. Sie würden zwei verschiedene Schema-Versionen der Datenbanktabelle benötigen, die gleichzeitig zugänglich sind und austauschbar verwendet werden können. Dies zu implementieren, wäre selbst bei einfachen Feldänderungen keine leichte Aufgabe, ganz zu schweigen von komplexeren Strukturänderungen. Und selbst wenn Sie dies für Datenbanktabellen schaffen würden, müssten Sie verschiedene Versionen von Autorisierungsobjekten, Bildschirmen und so gut wie jedem anderen Objekttyp unterstützen , auf die über die Codierung verwiesen werden kann oder die auf die Codierung verweist.
Meiner Meinung nach wird es innerhalb eines ABAP-Systems keine Branches geben – zumindest nicht in naher Zukunft. Die Unterstützung für parallele Branches wurde bei der Entwicklung des Systems nicht berücksichtigt, und man müsste das gesamte System auseinandernehmen und von Grund auf neu entwickeln, wobei wahrscheinlich die Abwärtskompatibilität an mehreren Stellen gebrochen würde und eine Vielzahl möglicher Fehlerquellen einführen. Die einzige Option, die uns bleibt, ist die Verwendung mehrerer Systeme – und da diese Option praktisch seit den Anfängen besteht (auch wenn sie erst vor kurzem erschwinglich geworden ist), gibt es eine Reihe von Möglichkeiten, eine Landschaft von Entwicklungssystemen zu strukturieren. Da dieser Text jedoch bereits eine beträchtliche Länge erreicht hat, muss dieses Thema auf einen anderen Artikel warten.