NIS2 & DORA Compliance sichern – Secure Java Code Upgrade

Software-Modernisierungs-Pyramide mit drei Ebenen: Fachlich, Architektur, Technisch. Beschriftung"Prozesse und Organisation" an der Seite.
  • Software-Modernisierung

Organisatorische Software-Modernisierung

Warum wir nicht nur Technik betrachten sollen.

 

Vor einige Zeit hat bei uns ein Modernisierungsprojekt gestartet. Es war nicht einfach durchzusetzen. Die Fachabteilung hat das Budget erst freigegeben, nachdem wir ihnen versprochen haben, dass wir auch ein großes Feature umsetzen. Aber jetzt geht es los. Wir führen eine Microservice Architektur ein, um endlich von unseren Monolithen wegzukommen. Die externe Firma, die wir dafür beauftragt haben, hat uns schon eine Reihe von Patterns vorgestellt, mit denen sie den alten Brocken aufteilen werden. 6 Monate sind geplant, dann haben wir endlich ein modernes System.

Modernisierung

Wahnsinn ist, immer wieder das Gleiche zu tun und andere Ergebnisse zu erwarten.“ (wahrscheinlich nicht von Albert Einstein).

Modernisierung bedeutet Veränderung. Als Techniker:innen denken wir dabei oft an Strangler Fig Patterns, neue Java Versionen, Kubernetes, Domain Driven Design und Hexagonale Architektur. Aber Softwaresysteme sind soziotechnische Systeme und um das Gesamtsystem nachhaltig zu ändern, müssen wir auch soziale und organisatorische Aspekte ändern. Sonst reproduzieren wir dieselben Probleme nur mit anderen Werkzeugen. In diesem Artikel befassen wir uns speziell mit sozialen und  organisatorischen Aspekten der Softwaremodernisierung.

Kontext

Space is big. You just won’t believe how vastly, hugely, mind-bogglingly big it is (Douglas Adams).

Softwareentwicklung ist ein weites Feld mit vielen unterschiedlichen Bereichen. Eine Wahrheit in einem Bereich lässt sich nicht unbedingt auf andere Bereiche übertragen. Wir haben unsere Erfahrungen mit großen (mehrere Millionen Lines of Code), datenlastigen, geschäftskritischen Anwendungen gesammelt, die individuell für einen Kunden entwickelt wurden.  Anwender:innen kommen meist aus Fachabteilungen, oft aus dem öffentlichen Bereich, Banken oder Versicherungen. Geschrieben vor mehr als 20 Jahren von Entwicklungsteams zwischen 10 und 50 Personen.

Die Symptome

Vielleicht haben wir ja gar kein Problem und unsere Situation ist ganz normal? Hier ein paar Hinweise, wann es sich auszahlen könnte weiter zu lesen:

  • Lange Releasezyklen (> 4 Wochen)
  • Hohe Personalfluktuation in der Entwicklung
  • Veraltete Libraries und Frameworks
  • Viele Entwickler:innen (>10) arbeiten an einem Deployment (Monolith)
  • Schätzungen für Änderungen sind unverständlich hoch
  • Unbekannte oder niedrige Testabdeckung
  • Codeteile, in die niemand eingreifen will

Warum?

 „Alle glücklichen Familien gleichen einander, jede unglückliche Familie ist auf ihre eigene Weise unglücklich.“ (Leo Tolstoi)

Wenn wir 2026 noch Java 8 verwenden, so kann das viele Gründe haben. Einige davon werden wir hier diskutieren, aber wenn wir wirklich was ändern wollen, werden wir letztendlich selber analysieren müssen, was die Ursachen sind.  (Spoiler: Zu wenig Zeit ist nicht der Grund.) Warum? Wenn wir die Ursache nicht finden, wissen wir nicht, was wir ändern sollen.

Der erste Schritt der Modernisierung kann daher eine Retrospektive zum Thema “Warum sind wir nicht modern?” sein. 

Sie machen keine Retrospektiven? Der Titel ist ein wenig hart, da könnte sich jemand angegriffen fühlen? Das würde nur zu Schuldzuweisungen führen? Gut, Sie haben den ersten Grund gefunden, warum Sie nicht modern sind. Fehlerkultur, Hinterfragen von Prozessen und der Wille zur ständigen Verbesserung sind wesentliche Aspekte moderner Softwaresysteme. Die IT-Branche zeichnet sich durch ständigen Wandel aus. Wir erwarten ständig neue Produkte und innovative Lösungen. Das bedeutet aber nicht nur, dass sich die Produkte verändern, auch die Prozesse müssen sich wandeln und die Beteiligten müssen bereit sein, zu lernen und sich zu wandeln. Das heißt, Veränderung ist Teil unserer täglichen Arbeit. Was bedeutet es daher, wenn wir Modernisierungsbedarf in unserer Software identifizieren? Haben wir dann unsere Arbeit nicht richtig gemacht?

Womit wir schon beim nächsten Punkt sind.

Modernisierung ist kein Projekt

Es wäre so angenehm. Ich werfe einmal einen Batzen Geld ein, dann bin ich modern und kann mich wieder meinen anderen Themen widmen. Warum ist das angenehm? Weil ich mich dann nicht ändern muss. Weil ich meine Organisation nicht ändern muss. Weil ich nicht an der Kultur arbeiten muss. Wenn Modernisierung als Projekt organisiert wird, kommt man einem modernen System ein oder zwei Schritte näher, verharrt dann aber wieder an der Stelle und das System veraltet bald wieder.

Wir müssen daher eine Organisation entwickeln, bei der Modernisierung ein inhärenter Bestandteil ist. Das beginnt bei der Finanzierung, geht über die Teamstrukturen und beeinflusst den Entwicklungsprozess. Das bedeutet nicht, dass man im Rahmen der Modernisierung nicht Projekte durchführen soll. Z.B. kann die Migration einer Applikation auf Kubernetes gut als Projekt durchgeführt werden, aber das ist dann eben nur ein Teil einer ständigen Anstrengung.

Projektorganisation zerstört Produkte

In Projekten, die ein hohes Maß an Vergreisung bzw. Technischer Schuld aufweisen, sehen wir oft, dass die Weiterentwicklung stark von einer Projektorganisation geprägt ist. Gewünschte Features werden zusammengefasst und als Vorhaben definiert. In Folge wird der Auftrag dafür extern oder an ein intern zusammengestelltes Projektteam vergeben. Nach der Umsetzung des Projektes wird das Projektteam wieder aufgelöst.

Trifft man auf so ein Produkt, werden viele der Probleme bald sichtbar. Hohe Komplexität und veraltete Komponenten sind einfach zu erkennen. Wie entstehen aber die Probleme und warum wurden sie nicht bereits behoben?

Wissen entsteht durch Erfahrung

Wenn Komplexität nicht unbedingt notwendig ist und vermieden werden kann (akzidentelle Komplexität), könnte man die Software ja gleich richtig schreiben? Leider ist am Beginn die Aufgabe meist nicht klar. Erst wenn man länger an dem Problem arbeitet, versteht man die Zusammenhänge gut. Um einfache Lösungen für komplexe Probleme zu finden, dauert es dann noch länger. Man baut daher notwendigerweise zuerst Komplexität auf und ist erst später, mit gewonnener Erfahrung, in der Lage, sie wieder abzubauen.

Motivation zur Verbesserung?

 „If it ain’t broke, don’t fix it.“ (Thomas Bertram Lance 1977 über Infrastruktur der USA)

Erst wenn man ein Problem gelöst hat, wenn ein Projekt fertig ist, versteht man das Problem gut genug, um es einfacher lösen zu können. Die Lösung ist komplexer als nötig, aber als Entwickler:innen versteht man sie und sie erfüllt ihren Zweck. War die Aufgabe Teil eines Projektes, so ist das Projekt zu Ende.  Der Projektmanager hat seine Ziele erreicht, die Entwickler:innen wechseln in ein anderes Projekt. Es gibt keine Motivation, die Lösung zu verbessern. Für das nächste Projekt wäre eine Vereinfachung hilfreich, es sollte daher am Beginn des nächsten Projekts vereinfacht werden. Aber dazu fehlt dann die Erfahrung.

Organisiert man daher komplexe Produktentwicklungen durch eine Serie von Projekten, zusätzlich mit wechselnden Teams, findet regelmäßige Komplexitätsverringerung nicht statt, die Komplexität steigt stetig, die Entwicklungsgeschwindigkeit sinkt, was zu Unzufriedenheit sowohl beim Management als auch bei den Techniker:innen führt.

Produktteams

Obige Überlegungen führen dazu, stabile Produktteams (Stream Aligned Teams) einzuführen, die Verantwortung über den gesamten Produktlebenszyklus übernehmen. Der Trend geht dahin Produktteams nach fachlichen Prozessen in  Domänen einzuteilen und Teamgrößen zwischen 5 und 9 zu wählen. Der Wunsch nach Verantwortung über den gesamten Produktlebenszyklus zieht allerdings ein weiteres Problem nach sich:

Diagramm eines fachlich orientierten Teams mit 5 Personen, verantwortlich für technische Aspekte und Projektmanagement, neben Icon von kognitiver Überlastung.

Wenn ein Team von 5 bis 9 Personen (typisches Scrum Team) für alle Aspekte des Software Lifecycles, von den Anforderungen bis zum Betrieb und darüber hinaus für Managementaufgaben vom Projektbudget bis zum Projektmarketing, verantwortlich ist, dann kommt es bei den Teammitgliedern zur kognitiven Überlastung. Wunderwuzzis, die alles können, gibt es leider nicht. Zu viel Multitasking führt zur Abnahme der Effizienz. Unser Ziel, die Effizienz des Teams durch Verkleinerung des Teams zu steigern, wird durch kognitive Überlastung konterkariert.

Wir müssen daher versuchen, dem Team Arbeit abzunehmen – aber so, dass die Verantwortung, die wesentlichen Entscheidungen, beim Team bleiben und dass keine zusätzlichen Engstellen eingebaut werden. Dazu kommen weitere Teamstrukturen ins Spiel.

Support Teams

Die folgende Einteilung zu Support-Teams folgt den Ausführungen in Team Topologies (Matthew Skelton, Manuel Pais: TeamTopologies: Organizing Business and Technology Teams for Fast Flow; It Revolution Press 2019).

Um kognitive Überlastung zu verhindern werden zusätzlich zu den Produktteams Support Teams eingeführt.

Diagramm zeigt Teamstrukturen: Enabling Team, Stream Aligned Team, Kompliziertes Subsystem Team und Platform Team.

Platform Team

Ein Platform Team nimmt den Stream Aligned Teams Arbeit ab, indem es Services und Werkzeuge zur Verfügung stellt, ohne dem Stream Aligned Team die Verantwortung für die Tätigkeit zu nehmen. 

Zum Beispiel ist der Deploymentprozess grundsätzlich sehr einfach: Installiere diese Applikationsversion zu diesem Zeitpunkt in dieser Umgebung. Dies kann mit wenigen Parametern festgelegt werden. Die technischen Details im Hintergrund aber sind kompliziert und es bedarf viel Wissen und Erfahrung, um sie gut zu implementieren. Das Platform Team übernimmt aber nicht die Aufgabe des Deployments selbst, auf den Knopf drückt jemand vom Stream Aligned Team.

Platform Teams sind eigenständige Organisationen mit eigenen Zielen und Strategien, nicht ein Pool von Ressourcen, aus dem sich Stream Aligned Teams bedienen.

Enabling Team

Während Platform Teams dauerhafte Services zur Verfügung stellen, helfen Enabling Teams temporär den Stream Aligned Teams, um gewisse Aspekte der Softwareentwicklung zu verbessern. Das kann z.B. das Verbessern des Requirements Engineering sein oder auch die Einführung eines neuen Tools in die Applikationslandschaft.

Enabling Teams sind Teams von Spezialisten, aber auch Enabling Teams sind keine Ressourcenpools, die alltägliche Arbeiten in den Stream Aligned Teams durchführen. Sie bringen effizient Know How ins Stream Aligned Team, sie nehmen eventuell Arbeit ab, die vorübergehend notwendig ist, aber danach ist das Stream Aligned Team wieder auf sich gestellt.

Complicated Subsystem Team

Gelegentlich kommt es vor, dass Teile einer Anwendung aus Geschäftsprozesssicht sehr einfach sind, dass sich dahinter aber eine sehr komplizierte Logik verbirgt. Das können z.B. sehr komplizierte Berechnungen mit Regelwerken sein, die im Endeffekt aber nur eine Zahl ausgeben. Unter Umständen ist ein Team von Experten nötig, um den Aspekt gut abzudecken. In solchen Fällen kann ein eigenes Complicated Subsystem Team geschaffen werden, das nur einen bestimmten Aspekt der Anwendung abdeckt.

Was modernisieren?

 „Wer zahlt schafft an“ (angeblich ein Softwarearchitekt als er ein eigenes Budget forderte)

Es gibt viele unterschiedliche Aspekte der Softwaremodernisierung. Wir teilen sie in drei Ebenen ein: Fachlich, Architektur und Technisch.

Software-Modernisierungs-Pyramide mit drei Ebenen: Fachlich, Architektur, Technisch. Beschriftung

Auf allen Ebenen spielen Organisation und Prozesse eine wesentliche Rolle.

Auf der untersten, technischen Ebene geht es um Infrastruktur, Code und Werkzeuge. Auf der mittleren Ebene geht es um Strukturen, Algorithmen und Patterns und auf der obersten Ebene geht es um fachliche Anforderungen, Features und Geschäftsprozesse. Zweck jeder Anwendung ist effektive und effiziente Unterstützung auf der fachlichen Ebene, aber um dies zu erreichen, müssen die unteren Ebenen gesund sein. Bricht eine der unteren Ebenen, stürzt auch die fachliche Ebene.

Häufig sind die Entscheidungsstrukturen so aufgesetzt, dass der Fachbereich die letztgültige Entscheidungsgewalt über das Budget hat. Der Fachbereich hat aber verständlicherweise vorrangig Interesse an der fachlichen Ebene. Die Folge ist, dass die fachliche Ebene der Modernisierung überbetont wird. Neue Features werden implementiert, ohne dass die Architektur- und Technik-Ebene eine geeignete Qualität aufweisen.

Um diesen Schiefstand zu bereinigen sollte der technische Bereich unabhängig vom Fachbereich Entscheidungen über Modernisierungsschritte auf den unteren Ebenen treffen können. Dafür ist unter anderem ein eigenes Budget notwendig.

Budget

“Share it fairly but don’t take a slice of my pie” (Pink Floyd, Money).

Unter Technischer Schuld verstehen wir den Aufwand, den wir in ein Softwaresystem investieren müssen, um vom aktuellen Stand zu einem den Anforderungen angemessenen Qualitätsniveau zu gelangen. Das Paradoxe daran ist aber die Tatsache, dass Technische Schuld in der Regel kein rein technisches Problem ist (Dr. Andrew Richard Brown: Taming Your Dragon: Addressing Your Technical Debt, Apress 2024 ). Wir akzeptieren technisch suboptimale Lösungen im Abtausch mit höherer Entwicklungsgeschwindigkeit und/oder geringeren Kosten. 

Das Problem sind aber nicht unbedingt die Schulden, die können wir auch später zahlen, sondern es sind die Zinsen. Bei jeder Interaktion mit dem Softwaresystem zahlen wir diese Zinsen: sinkende Entwicklungsgeschwindigkeit, sinkende Stabilität, sinkende Benutzerzufriedenheit, aber steigender Aufwand für die Behebung von Fehlern, schlechte Erweiterbarkeit und schlechtere Planbarkeit. Manchmal bekommen wir direkt eine Rechnung dafür, z.B. wenn wir für eine Datenbank Extended Lifecycle Support zahlen, weil wir sie nicht auf die aktuelle Version hochgezogen haben, aber oft haben wir keine Ahnung, wie viel Zinsen wir zahlen. 

In einer Mc Kinsey Studie aus 2020 bei der 50 CIOs von Finanz- und Technologieunternehmen mit Einnahmen von über 1 Milliarde US-Dollar befragt wurden, gaben ca. 70 % der Befragten an, dass sie mehr  als 10 % der Ausgaben für neue Projekte an Zinsen für technische Schuld ausgeben, ca. 30% sogar mehr als 20%. Dies ist ein beträchtlicher Teil. Um ihn zu verringern, muss er erst mal sichtbar gemacht werden. Dies ist ein Bereich, den wir oft vernachlässigen. Wir schaffen es nicht, die Kosten von technischer Schuld für den Geldgeber sichtbar zu machen. Hilfsmittel dafür wären mit Werkzeugen für Qualitätsmetriken wie z.B. SonarQube vorhanden. Gemäß dem Leitsatz “You get what you measure“, ist mit Metriken vorsichtig umzugehen, aber besser eine vorhandene Metrik verwenden als keine.

Neben den Zinsen, die für Technische Schuld anfallen, soll auch die vorhandene Schuld abgetragen werden. Auch hierfür sollte regelmäßig ein fixer Teil des Budgets vorgesehen werden. Je nach Reife und Änderungsbedarf des Produkts ist ein Anteil zwischen 30 und 50% des Gesamtbudgets für technische Wartung und Modernisierung angemessen.

Wesentlich ist, dass über den technischen Anteil des Buffets auch die für das Produkt technisch Verantwortlichen die Verfügungsgewalt haben.

Fazit

“Organizations which design systems […] are constrained to produce designs which are copies of the communication structures of these organizations.”  (Melvin Edward Conway, 1968).

Technische Probleme haben oft organisatorische Ursachen. Wollen wir die Probleme lösen, so müssen wir die sozialen Strukturen und die Kultur des soziotechnischen Systems Software analysieren und daran arbeiten. Wenn wir Monolithen aufteilen wollen, müssen wir Teams aufteilen. Wenn wir Überlastung vermeiden wollen, müssen wir an Support-Strukturen arbeiten. Wenn wir moderne Technik haben wollen, müssen wir Technikern Verantwortung und Budget übergeben. Dieser Prozess ist mit Anstrengung verbunden, mit Widerstand muss gerechnet werden, aber:

“If it hurts, do it more frequently, and bring the pain forward.” (Jez Humble).

Epilog

Ich hatte dir ja erzählt, dass wir vor einem Jahr ein Modernisierungsprojekt gestartet hatten. Ist das aber den Bach runtergegangen! Jetzt ist das Projekt zwar offiziell “fertig”, aber nur die Hälfte läuft auf Kubernetes und die Microservices sind ein Distributed-Monolith, wo sich jedes neue Feature  auf gut die Hälfte der Services auswirkt. Wir steigen uns immer noch gegenseitig auf die Zehen und es kennt sich niemand richtig mit dem neuen Zeug  aus. Die Externen sind weg, kein Geld mehr da. Völliges Chaos! Weißt du, ob wer Java Entwickler:innen sucht?

 

Die Autoren

Erhard Siegl

Geboren 1968 in Oberösterreich übersiedelte er nach der Matura nach Wien. Studium der Mathematik an der Universität Wien (Mag., Dr. rer nat) und der Carleton University Ottawa / Kanada (MSc). Nach Beendigung des Studiums arbeitete er einige Jahre als Softwareentwickler in München und zehn Jahre als Consultant in Wien bei Unisys, einem weltweit tätigen Unternehmen für Informationstechnologie mit Sitz in den USA. Es folgten einige Jahre als Consultant und Teilhaber bei Objectbay, einem oberösterreichischen IT-Dienstleister. 2014 gründete er die Gepardec IT Services GmbH in der er bis heute als Consultant, Geschäftsführer und Gesellschafter tätig ist.

Erhard Siegl, Geschäftführer der gepardec IT. Senior Software Engineer, Trainer.
Claudia Maderthaner, Senior Software Engineer

Claudia Maderthaner

Claudia Maderthaner (Jahrgang 1979) ist eine Software Entwicklerin mit Fokus auf Java, Software-Architektur und sichere Softwareentwicklung. Sie studierte Wirtschaftsinformatik und angewandtes Wissensmanagement an der Johannes Kepler Universität Linz sowie Information Security Management am Campus Hagenberg der Fachhochschule Oberösterreich. Sie arbeitet seit mittlerweile mehr als 15 Jahren als Entwicklerin im Java Enterprise Bereich und unterrichtet nebenher am Campus Hagenberg der Fachhochschule OÖ.

WordPress Cookie Plugin von Real Cookie Banner