Dirk Mahler über automatisierte Codeanalyse mit jQAssistant

Thorben Janssen im Gespräch mit Dirk Mahler über jQAssistant und dessen Verwendung zur explorativen Codeanalyse und automatisierten Validierung der Anwendungsstruktur.

In Pocket speichern vorlesen Druckansicht 2 Kommentare lesen
Lesezeit: 16 Min.
Von
  • Thorben Janssen

Es gibt viele interessante Menschen in der Java-Community, die mit ihrem Engagement in Java Specification Requests (JSRs) und Open-Source-Projekten die Entwicklung vorantreiben. Einige von ihnen möchte ich hier nach und nach vorstellen und mit ihnen über ihre Projekte sprechen. Dieses Mal habe ich mit Dirk Mahler über die Analyse von Java-Projekten und seine Arbeit am Open-Source-Projekt jQAssistant gesprochen.

Thorben Janssen: Hallo Dirk, erzähle uns doch bitte ein bisschen über dich. Wie bist du zur Softwareentwicklung gekommen, und was machst du heute?

Dirk Mahler

Dirk Mahler: Ich hatte als Kind schon eine Neugier für alles, was mit Technik zu tun hatte. Meine Eltern förderten das nach Kräften und schenkten mir eines Tages einen Elektronikbaukasten, aus dem ich mir einen MW-Detektor zusammenstöpseln konnte – es war einfach nur toll, als ich im Hörer Töne untermalt durch heftigstes Pfeifen vernehmen konnte! Schnell waren Lötkolben und Co. besorgt, eine Bastelzeitschrift abonniert und es folgten kleine Projekte. Ein Thermometer, das ich 1988 als 12-Jähriger zusammengebaut habe und seitdem im Hause meiner Eltern seinen Dienst verrichtete, wurde erst letztes Jahr abgeschaltet – jedoch nicht, weil es defekt gewesen wären ...

Ich habe 1989 die Schule gewechselt, und hier gab es gleich zwei Computer-Kabinette – für DDR-Verhältnisse echter Luxus! Der Kontakt zu den Rechenmaschinen entstand über Spiele, ziemlich schnell erwachte aber das Bedürfnis, selbst etwas zum "Wackeln" zu bringen. Die ersten Programmierschritte machte ich mit Basic auf einem KC85/2 und Pascal auf dem BIC A7105 – beides Z80-Maschinen. Kurz darauf schenkte mir mein Vater einen KC85/4, und waschechter Maschinencode wurde zur nächsten Herausforderung. Das war auf Dauer anstrengend, also wechselte ich zu Assembler. Irgendwann kam die erste x86-Maschine ins Haus, und eine Mischung aus Turbo Pascal und Assembler stellten die Basis für Programmierexperimente über mehrere Jahre dar. Ein kleiner Höhepunkt in dieser Zeit war der erfolgreiche Crack einer Zugangssperre zu einem Spiel, aber leider konnte ich diesen Erfolg mit niemandem öffentlich teilen ...

Es kam, wie es kommen musste: ich entschied mich für ein Informatikstudium an der TU Dresden, das aber mit meinen Basteleien und bisherigen Erfahrungen nur wenig zu tun hatte. Kurzum: Meine Motivation, ein guter Student zu sein, hielt sich in Grenzen. Im Nachhinein bereue ich das manchmal, wenn mir ein Stück fehlender Theorie bewusst wird. Dafür verbrachte ich viel Zeit in studentischen Gremien, wo ich als Ausgleich wertvolle Erfahrungen in Bezug auf Menschen, Interessen, Konflikte und deren Auflösung sammeln durfte. Nach geschlagenen acht Jahren war dann auch diese Phase vorüber, und es ergab sich eine Option, für ein Jahr in Chile Software zu entwickeln. Der Schwerpunkt lag auf PHP, und ich merkte schnell, dass ich diesen Weg nicht weiter verfolgen würde: Die unselige Mischung aus View und Logik sowie (zumindest damals) fehlender Typsicherheit verursachte mir einfach zu viel Kopfschmerzen.

Ich wurde jetzt auf Java aufmerksam und hatte das Glück, bei einem Dresdner Unternehmen eine Anstellung als Consultant zu finden, welches einen O/R-Mapper auf Basis von JDO (Java Data Objects, "Vorläufer" von JPA) entwickelte und entsprechende Dienstleistungen anbot. Abgesehen vom Aufbau technischer Skills gab es hier zwei Dinge, die mir bis heute sehr wertvoll erscheinen: Einerseits war es die Möglichkeit, in Kundenprojekte unterschiedlichster Branchen und Größenordnungen hineinzuschnuppern. Andererseits entstand dadurch immer wieder Druck, sich schnell in andere fachliche Domänen und Kulturen einarbeiten zu müssen. Das war und ist nach wie vor anstrengend, die gesammelten Erfahrungen ermöglichen aber verschiedene Blickwinkel auf konkrete Probleme – unbezahlbar!

Janssen: Was machst du privat, wenn du nicht gerade in der Softwareentwickelung unterwegs bist?

Mahler: Gibt es ein Leben außerhalb unseres Berufs? Nun ja, neben hin und wieder mal ein gutes (Nicht-Fach-)Buch lesen oder einen Film schauen sind es vor allem zwei Dinge: Ich höre gern und viel Radio, speziell den Deutschlandfunk und den vor allem am Wochenende. Mein Tag beginnt mit "Informationen am Morgen" und endet mit "Das war der Tag". Dazwischen gibt es ganz tolle Formate: "Querköpfe", "Das Wochenendjournal”, "Klassik, Pop etc.", "Essay & Diskurs" usw. Ein ganz besonderer Tipp: "Zwischentöne" am Sonntagnachmittag. Abgesehen davon, dass ich mich gut informiert und anspruchsvoll unterhalten fühle, schätze ich vor allem die Unaufgeregtheit, mit welcher der Sender daherkommt, das ist gut zum "Herunterkommen". Es erscheint vielleicht unpopulär, aber für DLF & Co. zahle ich meine Rundfunkgebühren gern.

Das zweite Steckenpferd ist Tanzen: Standard und Latein, keine Wettbewerbe, Hobby, einfach so. Dazu bin ich aber nicht freiwillig gekommen. Vielmehr gab es (ganz klischeehaft) vor ziemlich genau 10 Jahren sehr intensiven Druck aus meinem allernächsten persönlichen Umfeld. Ich hätte damals nicht im Entferntesten daran gedacht, dass es mir einmal Freude bereiten könnte! Heute ist es einfach schön, in einem Lied einen Rhythmus zu entdecken, zu dem man sich gemeinsam bewegen und darüber hinaus auch Stimmung ausdrücken kann. Einen wichtigen Anteil an dieser Entwicklung hat unsere Tanzlehrerin, die ich immer wieder gern weiterempfehle, weil es ihr einfach wichtiger ist, den Spaß an der Sache zu vermitteln, als auf dem letzten i-Tüpfelchen perfekter Technik zu bestehen. Ich denke, dass dies gerade auch in meinem Arbeitsumfeld ein wichtiger Faktor ist, der leider oftmals unterschätzt wird.

Janssen: Und womit verdienst du deine Brötchen?

Mahler: Seit 2008 bin ich Gesellschafter eines kleinen, aber – in aller Bescheidenheit – feinen Unternehmens in Dresden: der buschmais GbR. Meine Kollegen und ich sind als Consultants in Kundenprojekten verschiedenster Branchen und Rollen unterwegs: Entwicklung, Architektur, Prozessoptimierung, Training. Der technologische Schwerpunkt liegt auf Java, seinem Familienclan und Freundeskreis, abgedeckt wird alles zwischen Backend und Frontend. Interessant ist dabei immer der Spagat, aktuelle Entwicklungen zu verfolgen, aber nicht sofort auf jeder Hypewelle zu reiten. Wir wollen unseren Kunden zwar moderne, aber zugleich belastbare und vor allem nachhaltige Software anbieten. Hier die richtigen Einschätzungen zu treffen ist nicht immer leicht, aber wir haben schon einiges an Erfahrungen gesammelt und wachsen nach wie vor gern an Herausforderungen. Es ist auch einer der Gründe, weswegen wir uns stark in der lokalen Java-Community engagieren: Der Wissensaustausch bei Veranstaltungen beziehungsweise dem gemeinsamen Bier danach ist einfach unverzichtbar.

Janssen: Du bist Haupt-Contributor beim Open-Source-Projekt jQAssistant, das bei der strukturellen Analyse von Java-Projekten hilft. Wie bist du dazu gekommen, und was interessiert dich besonders am Thema Codeanalyse?

Mahler: "Problem trifft auf Technologie und Spieltrieb". Etwas ausführlicher: Ich war mehrfach als Lead-Developer, Architekt etc. (ich kann ehrlich gesagt mit Rollen, die nur als Titel auf Visitenkarten prangen, nicht viel anfangen, sie sagen zu wenig über Qualifikation aus ...) tätig und wurde dabei immer wieder mit der Herausforderung konfrontiert, dass es auch beim besten Projekt-Set-up und ehrlichen Willen aller Beteiligten sehr schwer ist, Architektur- und Design-Regeln selbst für mäßig komplexe Anwendungen effizient im Team zu kommunizieren.

Eines Tages kam Michael Hunger, ein alter und von mir hochgeschätzter Freund aus Schulzeiten, auf mich zu. Er arbeitet für Neo4j Inc., die Firma hinter der gleichnamigen Graphendatenbank, und überredete mich, mir diese einmal näher anzuschauen. Er zeigte mir einen Prototypen, der Java-Bytecode einlas, dessen Strukturen als Graphen in der Datenbank ablegte und mit der Cypher Query Language erstaunlich einfache Abfragen darüber ermöglichte. Die Neugier war geweckt, ich fing an, selbst herumzuexperimentieren, und entdeckte recht schnell, dass diese Technologie wahrscheinlich mein "Architekturregelkommunikationsproblem" lösen könnte. Ich gab dem Kind den Namen jQAssistant (oder kurz jQA), redete mit anderen Entwicklern darüber, stellte es bei der Java User Group Saxony vor, stieß auf reges Interesse, erhielt neue Ideen, entwickelte weiter, reichte Vorträge bei Konferenzen ein, redete dort, erhielt weitere Ideen, fand Mitstreiter, entwickelte weiter usw.

Das Thema ist inhaltlich so faszinierend, weil es das, was wir als Entwickler in Domänen wie Banken, E-Commerce, Industrie etc. anwenden, auf unser ureigenstes Tätigkeitsfeld übertragen können: Analysen über Strukturen und Daten in den vielfältigsten Ausprägungen, nur eben in der Welt der Software. Wir kämpfen tagtäglich mit großen Mengen Code, die eine recht unangenehme Eigenschaft haben: hohe Komplexität. Die Beschäftigung mit den Analysen schafft einerseits das Verständnis, wie diese durch Technologie oder Prozesse überhaupt erwächst und gegebenenfalls von vornherein verhindert werden kann. Andererseits hilft sie gleichzeitig, existierende Probleme systematisch zu erfassen, zu bewerten und in den Griff zu bekommen. Das ist eine Kombination aus Experimentieren, Verstehen und wiederum spürbarem Nutzen – mir macht das unglaublich Spaß!

Janssen: Was macht jQAssistant, und wie kann es mir bei der Codeanalyse helfen?

Mahler: jQAssistant kann direkt auf der Kommandozeile ausgeführt oder als Maven-Plug-in in den Build-Prozess einer Java-Anwendung eingebunden werden, es liest die Softwarestrukturen wie Java-Bytecode, XML-Deskriptoren oder Build-System-Informationen ein und legt sie in einer Graphendatenbank ab. Über diesen Strukturen können nun Abfragen ausgeführt werden. Dabei ergibt sich eine nach meinem Geschmack schöne Symbiose aus Fachdomäne und Technologie: Die Repräsentation der eingelesenen Daten als Graph fühlt sich recht natürlich an: Es gibt Knoten mit Labels (Class, Method) und getypte Beziehungen (DECLARES). Ausgedrückt in Ascii-Art mit "()" für Knoten bzw. "- ->" für Beziehungen und garniert mit Variablen ergibt sich "(c:Class)-[:DECLARES]->(m:Method)" und schon ist die Cypher-Abfrage über alle Klassen und ihre deklarierten Methoden fast fertig. Damit lassen sich grundsätzlich zwei Dinge bewerkstelligen:

Da ist zunächst die Freestyle-Exploration: Es können Metriken (z. B. Komplexität bestimmter Anwendungsteile, Änderungshäufigkeit von Dateien etc.) ermittelt oder Muster im Code aufgefunden werden. Letzteres erlaubt Impact-Analysen (welche Code-Teile sind potenziell von einer Änderung betroffen?) oder sehr effiziente Suchen jenseits der Möglichkeiten moderner IDEs. Eines meiner Lieblingsbeispiele: In einem über die Jahre gewachsenen Java-EE-Projekt tauchten zwei Methodenaufrufe stets kurz hintereinander auf. Die Ursache war schlicht ein Design-Fehler aus den Anfangstagen, der endlich einmal behoben werden sollte. Die entsprechende Abfrage war in wenigen Minuten formuliert und die betroffenen Stellen schnell lokalisiert. Eine manuelle Suche wäre hingegen sehr zeitaufwendig, monoton und vor allem fehleranfällig gewesen.

Dann ist da die Analyse innerhalb eines Build-Prozesses, also die Lösung meines "Architekturregelkommunikationsproblems". Dazu können entsprechende Abfragen als Regeln hinterlegt und automatisiert ausgeführt werden. Diese zerfallen in zwei grundlegende Kategorien: Konzepte und Constraints. Auf die Idee mit den Konzepten bin ich ein wenig stolz, obwohl sie eigentlich naheliegend ist: Sie ermöglichen die Anreicherung der eingelesenen Informationen um Begriffe aus der Architektur- beziehungsweise Designsprache des zu analysierenden Projektes. Das klingt abstrakt, wird aber greifbar, wenn aus einer Java-Klasse ein "Controller" oder einem Package ein "Module" oder "Layer" wird. Genau diese Begriffe können dann in Constraints verwendet werden, um Regelverletzungen zu ermitteln: "Finde alle Controller, die nicht im Layer mit dem Namen 'UI' liegen." Die Cypher-Abfrage ist formaler, aber nicht wirklich komplizierter: "MATCH (layer:Layer)-[:CONTAINS*]->(controller:Controller) WHERE NOT layer.layerName='UI' RETURN controller, layer."

Komplettiert wird das Ganze durch ein nettes Detail: Pflegt man die Entwicklerdokumentation eines Projekts im Code als AsciiDoc-Markup, können die Regeln dort direkt eingebettet werden. Das typische Auseinanderdriften von Dokumentation (üblicherweise Word-Dateien oder Wikis) und Anwendungsstrukturen wird damit verhindert. Regelverletzungen werden den Entwicklern unmittelbar beim Bauen (Arbeitsplatz bzw. CI-Server) gemeldet, beschreiben das Problem mit den Begriffen der Architektur- und Designsprache und verteilen damit ganz nebenbei das entsprechende Wissen über die verwendeten Konzepte unter den Projektbeteiligten. Notwendige Anpassungen an der Dokumentation können umgekehrt recht einfach vorgenommen werden, auch die Arbeit in Branches ist damit kein Problem mehr.

Janssen: In welchen Anwendungen und für welche Aufgaben wird jQAssistant typischerweise eingesetzt?

Mahler: Das Werkzeug ist eine Reaktion auf Schmerzen, die sich zwangsläufig aus Problemen der Softwareentwicklung über längere Zeiträume unter Beteiligung verschiedener Personen ergeben. Das findet man klassischerweise im Unternehmensumfeld, und genau hier wird jQA eingesetzt, die Technologiefelder sind Java EE, Spring, OSGi & Co. Die automatisierten Analysen dienen kontinuierlicher Qualitätssicherung in Ergänzung zu anderen Werkzeugen wie FindBugs oder CheckStyle. Der explorative Aspekt wird durch Architekten, Entwickler oder QA-Ingenieure je nach Bedarf genutzt: Dies sind zum Beispiel die oben beschriebenen Suchen nach komplexen Mustern oder die Identifikation von Hotspots im Code zur Risikoabschätzung und Planung von Refactorings.

Weitere Anwendungsfelder, die ich am Anfang gar nicht auf dem Schirm hatte, sich aber zunehmend stärker herauskristallisieren, sind automatisiertes Reporting beziehungsweise Auditing von Strukturen in sicherheitsrelevanten Umfeldern oder die Überprüfung von Artefakten, deren Entwicklung von Unternehmen an externe Anbieter ausgelagert wurden.

Ein spannendes Thema, dem wir uns gerade zuwenden, ist die Unterstützung bei der Restrukturierung beziehungsweise Zerlegung monolithischer Legacy-Anwendungen, die es im Java-Umfeld ja mittlerweile zuhauf gibt. Das wird natürlich durch die aktuelle Debatte über Microservices befördert. Die Frage ist hierbei, ob man wertvolles Wissen, das in einer bestehenden Altanwendung kodiert ist, einfach wegwirft und verbunden mit einigen Risiken neu aufbaut oder nicht vielleicht doch besser das Bestehende systematisch in einen modernen Architekturansatz überführen kann. jQAssistant kann hier wertvolle Unterstützung bei strukturellen Analysen und Aufwandsabschätzungen liefern.

Janssen: Was muss ich tun, um jQAssistant zu meinem Projekt hinzuzufügen und wo kann ich mehr darüber erfahren?

Mahler: Auf der Homepage des Projekts gibt es einen "Get Started"-Guide und eine Referenz-Dokumentation. Einen guten Überblick für die automatisierten Analysen ist ein aufgebohrter Fork der Spring PetClinic, welcher unter https://github.com/buschmais/spring-petclinic zu finden ist und den ich auch immer wieder bei Vorträgen für Demonstrationen verwende:

Empfohlener redaktioneller Inhalt

Mit Ihrer Zustimmmung wird hier eine Vimeo-Video (Vimeo LLC) geladen.

Ich bin damit einverstanden, dass mir externe Inhalte angezeigt werden. Damit können personenbezogene Daten an Drittplattformen (Vimeo LLC) übermittelt werden. Mehr dazu in unserer Datenschutzerklärung.

Die Einstiegsschwelle in jQA ist zugegebenermaßen nicht ganz so niedrig, wie ich es mir wünschen würde, auch die Dokumentation könnte an manchen Stellen besser sein. Ich empfehle auf jeden Fall, keine Scheu davor zu haben, Fragen oder Probleme in der Google-Group oder Stack Overflow zu platzieren, die Links finden sich auf der Projekt-Homepage. Derartiges Feedback ist übrigens ein kleiner, aber wichtiger Beitrag für Open-Source-Projekte!

Mehr Infos

Janssen: Gibt es noch andere Projekte, die du aktuell verfolgst?

Mahler: Neben den Kundenprojekten und jQA bleibt leider relativ wenig Platz für andere Dinge. Es gibt da aber noch ein kleines "Abfallprodukt", das sich "eXtended Objects" (kurz XO) nennt und eine Art JPA für NoSQL-Datenbanken darstellt. Das Key-Feature: anstelle von POJOs werden Interfaces gemappt. Das ist am Anfang etwas gewöhnungsbedürftig, bietet aber unglaubliche Flexibilität, die Stichworte lauten Mehrfachvererbung beziehungsweise Mixin. Wer neugierig ist, kann sich unter http://buschmais.github.io/extended-objects/doc/0.8.0/neo4j/ einen kurzen Eindruck davon verschaffen.

Janssen: Wo kann man dich finden, wenn man mehr Fragen zu dir und deinen Projekten hat?

Mahler: Das Projekt ist auf Twitter unter @jQAssistant vertreten, ich selbst bin unter @dirkmahler erreichbar. Wer es ein wenig klassischer mag, sollte die buschmais-Website besuchen, hier gibt es neben aktuellen Unternehmensneuigkeiten natürlich auch Telefonnummer und E-Mail-Adresse.

Außerhalb Dresdens findet man mich hin und wieder bei Java User Groups beziehungsweise Konferenzen, einfach die Augen offenhalten. Und wer zufälligerweise einmal in der sächsischen Landeshauptstadt weilt, kann meine Aufmerksamkeit recht spontan mit der Aussicht auf einen (guten) Kaffee auf sich ziehen...

Janssen: Vielen Dank für das Interview und viel Erfolg mit deinen Projekten. ()