{"id":71,"date":"2018-04-06T15:50:03","date_gmt":"2018-04-06T13:50:03","guid":{"rendered":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=71"},"modified":"2022-12-01T15:50:25","modified_gmt":"2022-12-01T14:50:25","slug":"werkzeuge-zur-erhaltung-der-softwarearchitektur-jqassistant-teil-13","status":"publish","type":"post","link":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=71","title":{"rendered":"Werkzeuge zur Erhaltung der Softwarearchitektur &#8211; jQAssistant &#8211; Teil 13"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">jQAssistant<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In den bisherigen Posts haben ich euch Werkzeuge mit feste Pr\u00fcfregeln vorgestellt. Mit den nun folgenden sehr interessanten Werkzeug wird die <strong>Codestruktur<\/strong> in einer Datenbank abgelegt und auf dieser \u00fcber eine Abfragesprache Analysen definiert. Beispiel f\u00fcr solche ABfragen sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wo fehlt eine Annotation?<\/li>\n\n\n\n<li>Analyse zyklischer Abh\u00e4ngigkeiten<\/li>\n\n\n\n<li>Welche Teile der Software werden nicht genutzt?<\/li>\n\n\n\n<li>Liegen alle Facades in einem Packge \u201e*.facade\u201c?<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">jQAssistant<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Die Software jQAssistant \u00fcbernimmt die Struktur des compilierten Codes in die Graphdatenbank Neo4j. In dieser Datenbank kann mit der Abfragesprache <a href=\"https:\/\/neo4j.com\/developer\/cypher-query-language\/\">Cypher<\/a> die Struktur analysiert und auf diesem Wege die Einhaltung der Architektur gepr\u00fcft werden. Der Ablauf f\u00fcr die Nutzung ist wie folgt<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>jQAssistant-Server mit DB Neo4j scannt die Artefakte, die ausgewertet werden sollen<\/li>\n\n\n\n<li>manuelle, explorative Analyse der Daten<\/li>\n\n\n\n<li>Automatische Analyse von gruppierten Regeln, die aus der manuellen Analyse entstanden sind (Regeln in XML oder AsciiDoc)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Welche Abfragen auf der Datenbank m\u00f6glich sind, wird \u00fcber Konzepte bestimmt, die als Plugins f\u00fcr jQAssistant bereitgestellt werden. Her gibt es Plugins f\u00fcr Java, JEE, JPA aber auch eine Vielzahl anderer z.B. f\u00fcr die Ergebnisse der statischen Codeanalyse, um diese zu visualisieren. Auch ist es m\u00f6glich weitere Konzepte selbst zu erstellen, um eigene Architekturmerkmale zu pr\u00fcfen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die erzeugten Regeln k\u00f6nnen einen Schweregrad (Severity) zugeordnet werden, \u00fcber den ein geordneter Abbau technischer Schulden gesteuert werden kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scannen von Artefakten<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Der erste Schritt f\u00fcr die Nutzung von jQAssistant ist es, die Abh\u00e4ngigkeiten zwischen Artefakten zu erzeugen (nat\u00fcrlich nach dem Download und dem Entpacken). Im Anschluss wird der Server gestartet und das analysieren der Daten kann beginnen. Ein Skript k\u00f6nnte wie folgt aussehen<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo Daten einlesen\n\/opt\/jqassistant\/bin\/jqassistant.sh scan -s \/opt\/jqassistant\/jqassistant\/store \n                      -reportDirectory \/opt\/jqassistant\/jqassistant\/report \n                      -f \/opt\/jqassistant\/source\/\n\necho erzeuge Pfade\n\/opt\/jqassistant\/bin\/jqassistant.sh analyze -s \/opt\/jqassistant\/jqassistant\/store \n                      -reportDirectory \/opt\/jqassistant\/jqassistant\/report \n                      -concepts classpath:Resolve\n\necho starte Server\n\/opt\/jqassistant\/bin\/jqassistant.sh server -s \/opt\/jqassistant\/jqassistant\/store \n                 -reportDirectory \/opt\/jqassistant\/jqassistant\/report \n                 -serverAddress 0.0.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nach dem Einlesen der Daten kann \u00fcber das Web-UI (die URL wird nach dem Start in der Shell ausgegeben) die erste Abfrage erstellt werden.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1021\" height=\"911\" src=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi1.png\" alt=\"\" class=\"wp-image-72\" srcset=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi1.png 1021w, https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi1-300x268.png 300w, https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi1-768x685.png 768w\" sizes=\"auto, (max-width: 1021px) 100vw, 1021px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Eine tabellarische Darstellung der Ergebnisse ist ebenfalls m\u00f6glich.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"699\" height=\"275\" src=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi2.png\" alt=\"\" class=\"wp-image-73\" srcset=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi2.png 699w, https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi2-300x118.png 300w\" sizes=\"auto, (max-width: 699px) 100vw, 699px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Inhalte der Datenbank<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Die Inhalte der Datenbank h\u00e4ngen 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\u00f6glichkeiten ersichtlich sind. Grunds\u00e4tzlich besteht eine Graphdatenbank erwarteter Weise aus Knoten (hier mit Properties[Key\/value] z.B. f\u00fcr Namen, Label) und Beziehungen (mit Properties, Richtung). Die grafische Anfrage GUI liefert uns alle Informationen, die wir zum arbeiten ben\u00f6tigen. Mit Hilfe des Punktes &#8222;Database Information&#8220; werden alle aktuell verwendeten Knotentypen und Beziehungstypen angezeigt<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"678\" height=\"748\" src=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi3.png\" alt=\"\" class=\"wp-image-74\" srcset=\"https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi3.png 678w, https:\/\/www.schoenberg-solutions.de\/arndtblog\/wp-content\/uploads\/2022\/12\/jqassi3-272x300.png 272w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Beispiel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Es folgt nun ein kleines Beispiel, um euch eine Idee des Arbeitens zu vermitteln.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MATCH\n (c:Class)-&#91;:DECLARES]->(m:Method)\nWHERE c.fqn =~ 'de.schoeso.*.*Facade'\n  AND NOT(m.name =~ '__cobertura.*')   AND NOT(m.name = '')\n  AND m.visibility = 'public' AND (m.static IS NULL OR m.static = false)\n  AND NOT((m)-&#91;:ANNOTATED_BY] -> \n       ()-&#91;:OF_TYPE] ->(:Type{name:'TransactionAttribute'}))\nRETURN c.name, m.name, m.static<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wie man in der Abfragesprache schon sieht sind die Kanten gerichtet. Es werden Klassen (Knoten vom Typ Class) gesucht, die eine Methode besitzen. Die &#8222;WHERE&#8220; Bedingung schr\u00e4nkt 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 &#8222;public&#8220; besitzen und nicht statisch sein. Abschlie\u00dfend werden jene Methoden gesucht, die <strong>keine<\/strong> Annotation vom Typ &#8222;TransactionAttribute&#8220; besitzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ergebnis wird hier als Liste dargestellt, kann aber immer auch als interaktiver Graph ausgegeben werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Abfragen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wie wir gesehen haben, ist jQAssistant ein sehr flexibles Werkzeug. Ich habe hier ein paar Abfragen f\u00fcr unseren Kontext zusammengestellt.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Allgemein\n<ul class=\"wp-block-list\">\n<li>Kein Java-Paket hat mehr als n Typen<\/li>\n\n\n\n<li>Keine Klasse hat mehr als n Methoden<\/li>\n\n\n\n<li>Test-Klassen-\/Methodenbezeichnungen beginnen mit Test<\/li>\n\n\n\n<li>Sehr gro\u00dfe Ableitungshierarchie sollen nicht existieren<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Entwurfsmuster\n<ul class=\"wp-block-list\">\n<li>Klassen mit mehr als n Konstruktoren ermitteln, um ggf. eine Factory zu definieren<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Ordnung insb. Schichtenbildung\n<ul class=\"wp-block-list\">\n<li>Keine zyklischen Artefakte, Packages, (Klassen) mit Pr\u00fcfung direkter \/ indirekter Abh\u00e4ngigkeiten<\/li>\n\n\n\n<li>Fachliche Schichten bei \u201eguten\u201c Paketnamen; gibt es ein fachliches Schema f\u00fcr die Pakete (z.B. Abrechnung, Stammdaten und kein technisches z.B. Entity, Facade), k\u00f6nnen fachliche Abh\u00e4ngigeiten sehr gut analysiert werden<\/li>\n\n\n\n<li>Vermeidung von \u201eSplit Packages\u201c (Pakete, die sich auf verschiedene Artefakte verteilen, um z.B. &#8222;protected&#8220; Methoden eine Lib nutzen zu k\u00f6nnen; diese sind im Java 9 Modulsystem nicht mehr erlaubt<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>EJB\n<ul class=\"wp-block-list\">\n<li>Jede Facade implementiert ihr Interface<\/li>\n\n\n\n<li>Facade implementieren Interfaces mit dem Namen der Facade als Pr\u00e4fix<\/li>\n\n\n\n<li>Public Facade Methoden finden sich im Interface<\/li>\n\n\n\n<li>Public Facade Methoden haben eine Annotation vom Typ @TransactionAttribute<\/li>\n\n\n\n<li>\u201eFind&#8230;\u201c Methoden haben ein Annotation @TransactionAttribute.Supports<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Web\n<ul class=\"wp-block-list\">\n<li>Im Web sind Injection von EJB immer local<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>EAR\n<ul class=\"wp-block-list\">\n<li>Welche Methoden aus Interfaces werden nicht mehr genutzt und k\u00f6nnen somit bereinigt \/ gel\u00f6scht werden<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integration<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eigene GUI<\/li>\n\n\n\n<li>Maven-Build mit Regelwerk (Abbruch nach Schweregrad der verletzten Regel)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Regeln<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Regeln werden innerhalb des Maven Plugins angegeben und ausgef\u00fchrt. Wird mindestens ein Ergebnis gefunden ist die Regel nicht erf\u00fcllt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;jqa:jqassistant-rules xmlns:jqa=\"http:\/\/www.buschmais.com\/jqassistant\/core\/analysis\/rules\/schema\/v1.0\">\n    &lt;constraint id=\"schoeso-rules:testClassPackageCount\" severity=\"critical\">\n        &lt;description>Kein Java-Paket hat mehr als 20 Typen&lt;\/description>\n        &lt;cypher>&lt;!&#91;CDATA&#91;\n           MATCH (p:Package)-&#91;CONTAINS]->(t:Type)\n           WHERE p.fqn =~ 'de\\\\.schoeso\\\\..*'\n             AND t.fqn =~ 'de\\\\.schoeso.&#91;^\\\\$]*'\n            WITH p, count(t) AS typeCount\n           WHERE typeCount > 20\n          RETURN p.fqn\n        ]]>&lt;\/cypher>\n    &lt;\/constraint>\n    &lt;!-- auch hier kann severity=\"critical\" gesetzt werden -->\n    &lt;group id=\"schoesoDefault\">\n        &lt;includeConstraint refId=\"schoeso-rules:testClassPackageCount\" \/>\n        &lt;includeConstraint refId=\"schoeso-rules:testTestClassName\" \/>\n    &lt;\/group>\n&lt;\/jqa:jqassistant-rules><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>jQAssistant In den bisherigen Posts haben ich euch Werkzeuge mit feste Pr\u00fcfregeln vorgestellt. Mit den nun folgenden sehr interessanten Werkzeug wird die Codestruktur in einer Datenbank abgelegt und auf dieser \u00fcber eine Abfragesprache Analysen definiert. Beispiel f\u00fcr solche ABfragen sind: jQAssistant Die Software jQAssistant \u00fcbernimmt die Struktur des compilierten Codes in die Graphdatenbank Neo4j. In [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-71","post","type-post","status-publish","format-standard","hentry","category-softwarearchitektur"],"_links":{"self":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/71","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=71"}],"version-history":[{"count":1,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":75,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/71\/revisions\/75"}],"wp:attachment":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}