Arndt Schönbergs Weblog

Freitag Mai 18, 2018

Spooky Exceptions (8) - Exception Description: Entity class [class ... ] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass

Umgebung

  • Wildfly 12
  • EE7
  • Eclipselink

Situation

Bei der Prüfung der persistence.xml beim Hochfahren des Servers wird folgende Exception geworfen:
 
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): 
org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class ...] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. 
If you have defined PK using any of these annotations then make sure that you do not have mixed access-type 
(both fields and properties annotated) in your entity class hierarchy.
In unserem Fall lag dies daran, dass es sich bei der betroffenen Entität um eine Entität handelte, die aus einer anderen abgeleitet ist. Die Parent-Entity liegt in einer ausgelagerten jar Datei, die neben der Projekt-Ejb Datei verwendet wurde. In der application.xml wurde aber vergessen, dies ausgelagerte Datei als ejb-Modul einzutragen. Dadurch konnte der Scanner die übergeordnete Klasse nicht erkennen und hat die in ihr enthaltene Annotation nicht auswerten können.

Montag Apr 23, 2018

Java Fat Clients - Java FX und Swing - Status

In diesem Blog nur ein kurzer Hinweis zu Fat Clients in Java.

Oracle wird JavaFX laut Java Client Roadmap Update 2018 ab Java SE 11 nicht mehr mit ausliefern. Somit wird aus JavaFX ein losgelöstes Community Projekt. Man darf gespannt sein, wie sich das weiter auf die Nutzung auswirkt und ob die aktuelle „Gemeinde“ groß genug ist.

Das andere Sorgenkind im Client Bereich - AWT und Swing - bleibt uns auf jeden Fall bis Java SE11 erhalten und soll sogar weiterentwickelt werden. Für mich als Fan von Swing eine gute Nachricht.

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

    Calendar

    Feeds

    Search

    Links

    Navigation