Arndt Schönbergs Weblog

Montag Apr 09, 2018

Werkzeuge zur Erhaltung der Softwarearchitektur - weitere Tools - Teil 15

Weitere Tools

In diesem Blog folgt zum Abschluss der Serie eine Auflistung von Werkzeugen / Frameworks, die ebenfalls einen Bezug zum Thema Architekturerhaltung haben.
  • JDepend
  • NCSS (veraltet)
  • SLOCCCount
  • Maven
  • IDE
  • JEE - gibt eine technische Schichtentrennung vor
  • FylWay (DB-Versionierung)
  • DB-Integrität
  • Code-Review
  • Sicherheit
  • OWASP (Sicherheit)
  • ZAProxy (Pen-Test)
    • Lizenzkostenpflichtig
  • Structure 101
  • Sonargraph
  • Alle Teile der Serie zu Architekturerhaltung in Java

    Freitag Apr 06, 2018

    Werkzeuge zur Erhaltung der Softwarearchitektur - Tools und Plugins - Teil 14

    Tools und Plugins

    In diesem Posts fasse ich die verschiedenen Werkzeuge, die in den letzten Posts angesprochen wurden, zusammen. Sie bieten eine sehr gute Basis um auf Basis von OpenSource professionelle Prüfungen für die Architekturerhaltung durchzuführen. Es ergibt sich ein bunter Strauß an Werkzeugen mit einer noch größeren Anzahl an Plugins. Eine sinnvolle Nutzung macht aber euch das Leben leichter und eure Kunden glücklich.

    IDE am Beispiel von MyEclipse / Android-Studio

    • PMD
    • CheckStyle
    • FindBugs
    • SonarQube
    • JaCoCo
    • Selenium
    • (JUnit)
    • (Tasks)

    SCM am Beispiel von SVN

    • PreCommit Hook

    Build-System am Beispiel von Maven

    • PMD
    • CheckStyle
    • FindBugs
    • Surefire
    • JaCoCo
    • Selenium
    • FlyWay
    • WildFly
    • jQAssistant
    • Project-Info-Reports
    • Site

    CI-System am Beispiel von Jenkins

    • PMD
    • CheckStyle
    • FindBugs
    • DRY
    • SonarQube
    • JUnit
    • JaCoCo
    • Sonar QualityGate
    • Task Scanner
    • Dashboard View
    • Static Analysis Collector
    • Static Analysis Utilities

    SonarQube

    • PMD
    • CheckStyle
    • FindBugs
    • SoftVis3D
    • Sonar-Regeln

    jQAssistant

    • Konzepte für JEE und Java

    Alle Teile der Serie zu Architekturerhaltung in Java

    Werkzeuge zur Erhaltung der Softwarearchitektur - jQAssistant - Teil 13

    jQAssistant

    In den bisherigen Posts haben ich euch Werkzeuge mit feste Prüfregeln vorgestellt. Mit den nun folgenden sehr interessanten Werkzeug wird die Codestruktur in einer Datenbank abgelegt und auf dieser über eine Abfragesprache Analysen definiert. Beispiel für solche ABfragen sind:
    • Wo fehlt eine Annotation?
    • Analyse zyklischer Abhängigkeiten
    • Welche Teile der Software werden nicht genutzt?
    • Liegen alle Facades in einem Packge „*.facade“?

    jQAssistant

    Die Software jQAssistant übernimmt die Struktur des compilierten Codes in die Graphdatenbank Neo4j. In dieser Datenbank kann mit der Abfragesprache Cypher die Struktur analysiert und auf diesem Wege die Einhaltung der Architektur geprüft werden.

    Der Ablauf für die Nutzung ist wie folgt
    • jQAssistant-Server mit DB Neo4j scannt die Artefakte, die ausgewertet werden sollen
    • manuelle, explorative Analyse der Daten
    • Automatische Analyse von gruppierten Regeln, die aus der manuellen Analyse entstanden sind (Regeln in XML oder AsciiDoc)
    Welche Abfragen auf der Datenbank möglich sind, wird über Konzepte bestimmt, die als Plugins für jQAssistant bereitgestellt werden. Her gibt es Plugins für Java, JEE, JPA aber auch eine Vielzahl anderer z.B. für die Ergebnisse der statischen Codeanalyse, um diese zu visualisieren. Auch ist es möglich weitere Konzepte selbst zu erstellen, um eigene Architekturmerkmale zu prüfen.

    Die erzeugten Regeln können einen Schweregrad (Severity) zugeordnet werden, über den ein geordneter Abbau technischer Schulden gesteuert werden kann.

    Scannen von Artefakten

    Der erste Schritt für die Nutzung von jQAssistant ist es, die Abhängigkeiten zwischen Artefakten zu erzeugen (natürlich nach dem Download und dem Entpacken). Im Anschluss wird der Server gestartet und das analysieren der Daten kann beginnen. Ein Skript könnte wie folgt aussehen
    echo Daten einlesen
    /opt/jqassistant/bin/jqassistant.sh scan -s /opt/jqassistant/jqassistant/store 
                          -reportDirectory /opt/jqassistant/jqassistant/report 
                          -f /opt/jqassistant/source/
    
    echo erzeuge Pfade
    /opt/jqassistant/bin/jqassistant.sh analyze -s /opt/jqassistant/jqassistant/store 
                          -reportDirectory /opt/jqassistant/jqassistant/report 
                          -concepts classpath:Resolve
    
    echo starte Server
    /opt/jqassistant/bin/jqassistant.sh server -s /opt/jqassistant/jqassistant/store 
                     -reportDirectory /opt/jqassistant/jqassistant/report 
                     -serverAddress 0.0.0.0
    
    Nach dem Einlesen der Daten kann über das Web-UI (die URL wird nach dem Start in der Shell ausgegeben) die erste Abfrage erstellt werden.

    Eine tabellarische Darstellung der Ergebnisse ist ebenfalls möglich.

    Inhalte der Datenbank

    Die Inhalte der Datenbank hängen von den Konzepten ab. Ein Schema wie bei RDMS gibt es bei Graphdatenbanken nicht. Nicht alle Konzepte sind derzeit so gut dokumentiert, dass aus der Dokumentation die Abfragemöglichkeiten ersichtlich sind. Grundsätzlich besteht eine Graphdatenbank erwarteter Weise aus Knoten (hier mit Properties[Key/value] z.B. für Namen, Label) und Beziehungen (mit Properties, Richtung). Die grafische Anfrage GUI liefert uns alle Informationen, die wir zum arbeiten benötigen. Mit Hilfe des Punktes "Database Information" werden alle aktuell verwendeten Knotentypen und Beziehungstypen angezeigt

    Beispiel

    Es folgt nun ein kleines Beispiel, um euch eine Idee des Arbeitens zu vermitteln.
    MATCH
     (c:Class)-[:DECLARES]->(m:Method)
    WHERE c.fqn =~ 'de.schoeso.*.*Facade'
      AND NOT(m.name =~ '__cobertura.*')   AND NOT(m.name = '')
      AND m.visibility = 'public' AND (m.static IS NULL OR m.static = false)
      AND NOT((m)-[:ANNOTATED_BY] -> 
           ()-[:OF_TYPE] ->(:Type{name:'TransactionAttribute'}))
    RETURN c.name, m.name, m.static
    
    Wie man in der Abfragesprache schon sieht sind die Kanten gerichtet. Es werden Klassen (Knoten vom Typ Class) gesucht, die eine Methode besitzen. Die "WHERE" Bedingung schränkt dies weiter ein. Es sollen nur Klassen mit einem speziellen Namen (und damit auch Package) betrachtet werden. Cobertura Klassen und Konstruktoren sollen nicht betrachtet werden. Die betrachteten Methoden sollen den Sichtbarkeitsmodifikator "public" besitzen und nicht statisch sein. Abschließend werden jene Methoden gesucht, die keine Annotation vom Typ "TransactionAttribute" besitzen.

    Das Ergebnis wird hier als Liste dargestellt, kann aber immer auch als interaktiver Graph ausgegeben werden.

    Abfragen

    Wie wir gesehen haben, ist jQAssistant ein sehr flexibles Werkzeug. Ich habe hier ein paar Abfragen für unseren Kontext zusammengestellt.
    • Allgemein
      • Kein Java-Paket hat mehr als n Typen
      • Keine Klasse hat mehr als n Methoden
      • Test-Klassen-/Methodenbezeichnungen beginnen mit Test
      • Sehr große Ableitungshierarchie sollen nicht existieren
    • Entwurfsmuster
      • Klassen mit mehr als n Konstruktoren ermitteln, um ggf. eine Factory zu definieren
    • Ordnung insb. Schichtenbildung
      • Keine zyklischen Artefakte, Packages, (Klassen) mit Prüfung direkter / indirekter Abhängigkeiten
      • Fachliche Schichten bei „guten“ Paketnamen; gibt es ein fachliches Schema für die Pakete (z.B. Abrechnung, Stammdaten und kein technisches z.B. Entity, Facade), können fachliche Abhängigeiten sehr gut analysiert werden
      • Vermeidung von „Split Packages“ (Pakete, die sich auf verschiedene Artefakte verteilen, um z.B. "protected" Methoden eine Lib nutzen zu können; diese sind im Java 9 Modulsystem nicht mehr erlaubt
    • EJB
      • Jede Facade implementiert ihr Interface
      • Facade implementieren Interfaces mit dem Namen der Facade als Präfix
      • Public Facade Methoden finden sich im Interface
      • Public Facade Methoden haben eine Annotation vom Typ @TransactionAttribute
      • „Find...“ Methoden haben ein Annotation @TransactionAttribute.Supports
    • Web
      • Im Web sind Injection von EJB immer local
    • EAR
      • Welche Methoden aus Interfaces werden nicht mehr genutzt und können somit bereinigt / gelöscht werden

    Integration

    • Eigene GUI
    • Maven-Build mit Regelwerk (Abbruch nach Schweregrad der verletzten Regel)

    Regeln

    Regeln werden innerhalb des Maven Plugins angegeben und ausgeführt. Wird mindestens ein Ergebnis gefunden ist die Regel nicht erfüllt.
    <jqa:jqassistant-rules xmlns:jqa="http://www.buschmais.com/jqassistant/core/analysis/rules/schema/v1.0">
        <constraint id="schoeso-rules:testClassPackageCount" severity="critical">
            <description>Kein Java-Paket hat mehr als 20 Typen</description>
            <cypher><![CDATA[
               MATCH (p:Package)-[CONTAINS]->(t:Type)
               WHERE p.fqn =~ 'de\\.schoeso\\..*'
                 AND t.fqn =~ 'de\\.schoeso.[^\\$]*'
                WITH p, count(t) AS typeCount
               WHERE typeCount > 20
              RETURN p.fqn
            ]]></cypher>
        </constraint>
        <!-- auch hier kann severity="critical" gesetzt werden -->
        <group id="schoesoDefault">
            <includeConstraint refId="schoeso-rules:testClassPackageCount" />
            <includeConstraint refId="schoeso-rules:testTestClassName" />
        </group>
    </jqa:jqassistant-rules>
    

    Alle Teile der Serie zu Architekturerhaltung in Java

    Mittwoch Apr 04, 2018

    Werkzeuge zur Erhaltung der Softwarearchitektur - SonarQube - Teil 12

    SonarQube

    Bei SonarQube handelt es sich um ein Serverprodukt, das eine sehr gute Übersicht für den manuellen Prozess bietet. Auch wird der zeitliche Verlauf von Regelverletzungen in einer Datenbank gespeichert, so dass die Historie gut zu verfolgen ist. Sonar benötigt mindestens einen eigenen Server, der über Plugins erweitert wird und die Daten in einem DBMS ablegt. Die folgende Abbildung zeigt die Zusammenfassung eines Projektes in SonarQube

    Sonar Projekt

    Wir benutzen derzeit SonarQube primär für den manuellen Sicherungsprozess, da die automatischen Regeln sehr gut durch die zuvor vorgestellten Werkzeuge in den Ablauf integriert sind. Sonar verwendet eine Vielzahl von Regeln und kann unter anderem auch auf die Regeln der bisherigen Werkzeuge zugreifen. Für den manuellen Review Prozess ist besonders schön, dass bei Sonar
    • alles gut Integriert ist
    • eine grafische Aufbereitung der Werte (auch Städte) stattfindet
    • der zeitlicher Verlauf in einer Datenbank abgelegt wird
    • False/Positives, die ein Hauptbestandteil des manuellen Prozesses sind, gut verwaltet werden
    Eine Darstellung von Werten als Stadt findet sich in der folgenden Grafik.

    Code City

    Außerdem bewertet SonarQube technischen Schulden in Arbeitszeit mit einer (aus meiner Sicht sehr einfachen) Metrik. Dies kommt häufig dem Management mehr entgegen, als Zahlen zu Bugs und Code-Smells. Aber Vorsicht, solche Werte können niemals sehr genau sein.

    Quality Gates

    SonarQube fasst die Ergebnisse der Projektanalysen zusammen und stellt sogenannt Quality Gates bereit. Diese können Sonar konfiguriert werden und beschreiben analog zu Jenkins eine Art "Gesundheitszustand" des Projekts. Quality Gates fassen Schwellwerte für verschiedene Bereiche zusammen
    • Veränderte Testabdeckung
    • Regelverstöße
    • Neue blockierende Regelverstöße
    • Neue kritische Regelverstöße
    • Technical Debt Ratio on New Code
    • Doppelter Quellcode
    • usw.

    Integration

    • IDE (Plugin unvollständig)
    • Maven-Build
    • Jenkins (Plugin defekt)
      • Quality Gate Plugin
      • https://issues.jenkins-ci.org/browse/JENKINS-43081
    • Sonar-Server
    Die Plugins sind derzeit etwas "wackelig" und nicht zu 100% einsatzfähig. Auch wegen dieser derzeit schlechten Plugin-Situation ist Sonar derzeit eher für den manuellen Prozess sinnvoll. Die Plugins für die IDE zeigen derzeit Fehler entsprechend der Konfiguration des Servers. Es ist möglich Projekte mit den SonarQube Projekten zu „verbinden“ und somit die projektspezifischen Status einzusehen. Eine False/Positiv Behandlung in der IDE ist aber derzeit nicht (mehr) möglich.

    False/Positive

    Eine der Stärken von SonarQube ist die False/Positive Behandlung. Bei False/Positives kann in Sonar festgehalten werden, warum es sich um einen False/Positive handelt und die Begründung in einer Datenbank gespeichert werden. Danach gilt der False/Positive als behandelt und erscheint nicht mehr in den Auswertungen.

    Regelerweiterung

    • Eigener Regelsatz / Selektion
    • https://docs.sonarqube.org/display/SONAR/Rules
    • Import weiterer Regelsätze z.B. der bisher betrachteten Werkzeuge

    Fazit

    SonarQube ist ein schickes Managementtool mit Integrationsschwierigkeiten. Nachdem die zuvor beschriebenen Werkzeuge in den QS Prozess aufgenommen wurden, sollte auch SonarQube insbesondere für den manuellen Prozess verwendet werden.

    Alle Teile der Serie zu Architekturerhaltung in Java

    Werkzeuge zur Erhaltung der Softwarearchitektur - FindBugs - Teil 11

    FindBugs

    Der dritte im Bunde der "magischen drei" ist FindBugs. FindBugs hat eine fantastische Fehlererkennung. Wir hatten intern bereits öfter Diskussionen zu den angezeigten Meldungen und mussten im Allgemeinen am Ende immer die Meldungen von FindBugs bestätigen. Im Gegensatz zu den anderen Tools analysiert FindBugs den Byte-Code.

    Besonderheiten

    • bestes Werkzeug für Fehlerprüfungen (NPE, ...)
    • Prüfung logischer Ausdrücke

    Integration

    • IDE
    • Maven-Build (Ausführung und Erzeugen von Basisdaten)
    • Jenkins (GUI und Grenze für ungültige Artefakte)
    Ein (einfacher) SVN Pre-Commit Hook Einsatz ist hier natürlich nicht möglich, da FindBugs den Byte-Code analysierert, der erst erzeugt werden müsste.

    False/Positive

    • Parametrisierung
    • Codestellen über Annotation von der Prüfung ausschließen
    • Ausschluss von Projekten / Packages

    Regelerweiterung

    • Externe Erweiterungen: z.B. Security Regeln http://find-sec-bugs.github.io/
    • Eigene Regeln in Java mit Wissen über ByteCode erstellen
    • https://www.ibm.com/developerworks/library/j-findbug2/
    Beispiel Blacklist für Regeln
    <?xml version="1.0" encoding="UTF-8"?>
    <FindBugsFilter>
        <Match>
            <Bug code="EI,EI2,Se,SECSQLIJPA,SECHCP,SECPTI,SECCI,SECPTO,SECUR" />
        </Match>
        <Match>
            <Class name="~.*\.R\$.*" />
        </Match>
        <Match>
            <Class name="~.*\.Manifest\$.*" />
        </Match>
    </FindBugsFilter>
    

    Stand bis hierher

    Mit den bis hier vorgestellten Werkzeugen haben wir die Pflicht der QS sichergestellt. Mit der Grundausstattung Open Tasks, FindBugs, PMD und Checkstyle können eine Vielzahl technischer Schulden vermieden und automatisch gefunden werden. Die Regeln sind bei allen Tools konfigurierbar und können sukzessive eingeführt werden.

    Aus meiner Sicht sollte niemand auf dies Tools verzichten. Wenn im aktuellen Projekt noch zu viele Probleme existieren, kann mit kleinen Regelsätzen gearbeitet werden. Wenn die Integration in den Build-Prozess nicht möglich ist, können die Werkzeuge auch nur in der IDE eingesetzt werden.

    Alle Teile der Serie zu Architekturerhaltung in Java

    Calendar

    Feeds

    Search

    Links

    Navigation