Zeigende Hände, wie viele von uns verstehen wirklich, wie Ihr Build-Automation-Tool seinen Abhängigkeitsbaum erstellt? Nun, senkt die Hand, wenn Sie verstehen, weil Sie an der Erstellung von Build-Automatisierungstools arbeiten. Dachte ich mir!
Eine frustrierende Verantwortung von Softwareingenieuren ist es, die Abhängigkeiten Ihres Projekts zu verstehen: welche transitiven Abhängigkeiten eingeführt wurden und von wem; warum v1.3.1 verwendet wird, wenn v1.2.10 deklariert wurde; was geschah, als die transitiven Abhängigkeiten sich änderten; wie kam es zu mehreren Versionen desselben Artefakts?
Jeder Softwareentwickler hat einen Abhängigkeitsbaum in eine Textdatei gespeist, nach spezifischen Artefakten gesucht und dann ihren Weg zurück zur Identifizierung ihrer Herkunft gegangen. Für alles andere als triviale Projekte ist es äußerst schwierig, wenn nicht unmöglich, eine mentale Karte der Abhängigkeiten zu erstellen.
I faced this problem when starting a new job with a mature code base, presenting a challenge to assemble the puzzle pieces. I’ve previously worked with graph databases and thought a graphical view of the dependency artifacts could be created using Neo4J, which resulted in DependencyLoader.
Hinweis: Dies ist kein Tutorial zu Graphendatenbanken, noch erfordert dieses Tutorial einen Hintergrund in Graphendatenbanken. Interessierte finden bei Neo4J Tutorials und White Papers, um anzufangen.
Einrichten der Umgebung
Java installieren
Java 11 oder später ist erforderlich. Falls noch nicht vorhanden, installieren Sie Ihre bevorzugte OpenJDK-Variante.
Installieren Sie Neo4J
Das Tutorial erfordert eine Neo4J-Datenbank, in die die Abhängigkeitsinformationen geladen werden. Es wird ein nicht geteilter Datenbankzustand empfohlen, da der Loader die Datenbank vor jedem Durchlauf löscht. Darauf wurden Sie hingewiesen!
Neo4J bietet persönliche Sandkästen, die für kurzfristige Projekte wie dieses Tutorial ideal sind.
Alternativ können Sie Neo4J lokal auf Ihrem Desktop oder Laptop installieren. Homebrew vereinfacht die Installationen unter MacOS:
brew install neo4j && brew services start neo4j
Bevor Sie fortfahren, bestätigen Sie den Zugriff auf Ihre Neo4J-Datenbank über den Browser, entweder über den Link und die Zugangsdaten für den Neo4J-Sandbox oder lokal unter http://localhost:7474. Die Standardanmeldedaten für eine lokale Installation sind neo4j/neo4j; nach erfolgreichem Login müssen Sie das Passwort ändern.
Repositories klonen
Das neo4j-gradle-dependencies Repository enthält die für das Laden von Abhängigkeiten in Neo4J. Dieses Tutorial erstellt einen Abhängigkeitsgraphen für spring-boot. Sie müssen diese beiden Repositories klonen.
Scott.Sosna@mymachine src% git clone [email protected]:scsosna99/neo4j-gradle-dependencies.git
Scott.Sosna@mymachine src% git clone [email protected]:spring-projects/spring-boot.git
Hinweis: Lokales Gradle ist nicht erforderlich, da beide Repositories den Gradle Wrapper verwenden, der beim ersten Gebrauch des Wrappers alle notwendigen Komponenten herunterlädt.
Abhängigkeiten erzeugen
DependencyLoader
nimmt die von Gradle generierte Abhängigkeitsbaum als Eingabe. Obwohl mehrere Konfigurationen zusammen geladen werden können — z.B. compileClasspath
, runtimeClasspath
, testCompileClasspath
, testRuntimeClasspath
— ist es zum Erlernen, insbesondere für ein Tutorial, einfacher, mit einer einzigen Konfiguration zu beginnen.
Um Abhängigkeiten für alle Konfigurationen zu erzeugen:
gradle dependencies
./gradlew dependencies
Um Abhängigkeiten für eine einzelne Konfiguration zu erzeugen
gradle dependencies --configuration <configuration>
./gradlew dependencies --configuration <configuration>
Spring Boot Abhängigkeiten erzeugen
Dieses Tutorial erstellt einen Abhängigkeitsgraphen in Neo4J unter Verwendung der compileClasspath
-Abhängigkeiten von Spring Boot. Führen Sie die folgenden Befehle aus dem Verzeichnis aus, in dem die Repositorys geklont wurden:
Scott.Sosna@mymachine src% cd spring-boot/spring-boot-project/spring-boot
Scott.Sosna@mymachine spring-boot% ./gradlew dependencies --configuration compileClasspath > dependencies.out
Die Datei dependencies.out
enthält die Kompilationszeit-Klassenpfad-Abhängigkeiten für Spring Boot.
Abhängigkeiten Laden
Zunächst bestätigen Sie die Verbindungs-URL und die Authentifizierungscredentials in DependencyLoader.java und ändern Sie sie gegebenenfalls.
Führen Sie die folgenden Befehle aus, um die Spring Boot-Abhängigkeiten in Neo4j zu laden:
Scott.Sosna@mymachine spring-boot% cd ../../../neo4j-gradle-dependencies
Scott.Sosna@mymachine neo4j-gradle-dependencies% ./gradlew clean run --args="../spring-boot/spring-boot-project/spring-boot/dependencies.out"
Bei Erfolg lauten die Ausgabelinen von Gradle:
Scott.Sosna@PVHY32M6KG neo4j-gradle-dependencies % ./gradlew clean run --args="../spring-boot/spring-boot-project/spring-boot/dependencies.out"
> Task :compileJava
Note: /Users/Scott.Sosna/data/src/github/neo4j-gradle-dependencies/src/main/java/dev/scottsosna/neo4j/gradle/relationship/DependsOn.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :run
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Jun 02, 2023 6:19:22 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Direct driver instance 1606286799 created for server address localhost:7687
dependencies.out completed.
Jun 02, 2023 6:19:23 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Closing driver instance 1606286799
Jun 02, 2023 6:19:23 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Closing connection pool towards localhost:7687
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 3s
Abhängigkeiten Anzeigen
Es stehen mehrere Tools zur Verfügung, um Neo4J-Graphen anzuzeigen, aber das integrierte Browser-Tool ist für dieses Tutorial ausreichend.
Den vollständigen Baum anzeigen
Die Abfrage MATCH(a) RETURN a
ist das relational-äquivalente von SELECT * FROM <table>
Details eines Artefakts anzeigen
Jedes gefundene Artefakt erzeugt einen Knoten, dessen Eigenschaften das Artefakt (groupId/artifactId) und seinen Typ identifizieren, der im rechten Seitenbereich angezeigt wird.
Details ansehen einer Abhängigkeit
Jede Abhängigkeit wird als Beziehung erstellt, deren Eigenschaften die spezifischen Details der Abhängigkeit identifizieren: Konfiguration, angegebene/Version und Konfiguration. Die unten ausgewählte Abhängigkeit zeigt, dass spring-security:spring-web auf io.micrometer:micrometer-observation abhängt, aber die spezifizierte Version 1.10.7 von spring-web wurde als Version 1.11.0 aufgelöst.
Abhängigkeiten durchlaufen
Neo4J ermöglicht es Ihnen, den Graphen Knoten für Knoten zu erkunden, indem Sie den Graphen Knoten für Knoten manuell erweitern, und bietet eine Möglichkeit, bestimmte Bereiche des Abhängigkeitsbaums zu erkunden.
Angenommen, Sie möchten die Abhängigkeiten für das Artefakt io.projectreactor.netty:reactor-netty-http verstehen. Zuerst werden wir Neo4J für diesen spezifischen Knoten abfragen.
MATCH(a:Artifact {groupId: 'io.projectreactor.netty', artifactId: 'reactor-netty-http'}) RETURN a
Doppelklicken Sie auf den Knoten, um seine benachbarten Knoten anzuzeigen — das Artefakt(e), auf das es angewiesen ist, und die Artefakt(e), auf die es angewiesen ist.
Diese erweiterte Grafik zeigt ein Artefakt, das auf es angewiesen ist — die Wurzel des Projekts mit einem Artefakttyp PROJECT und sechs anderen Abhängigkeiten, auf die es angewiesen ist.
Als Nächstes doppelklicken Sie auf io.netty:netty-codehttps://github.com/netty/netty/tree/4.1/codec-httpc-http, um die nächste Ebene von Abhängigkeiten anzuzeigen. Beachten Sie, dass neben den Beziehungen (Abhängigkeiten) des ausgewählten Knotens zusätzliche Beziehungen für bereits im Graphen vorhandene Knoten angezeigt werden können.
Identifizieren von Versionen-Mismatch
Die Abhängigkeitsausgabe von Gradle zeigt an, wo die angegebene Version nicht die von Gradle aufgelöste Version war. Die Eigenschaften der Abhängigkeit (Beziehung) können in einer Neo4J-Abfrage verwendet werden, um die angezeigten Beziehungen und die angehängten Artefakte (Knoten) einzuschränken.
MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURN a,b,d
Neo4J kann Ergebnisse bei Bedarf in tabellarischer Form zur einfacheren Überprüfung zurückgeben.
MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURNa.name AS source, b.name AS dependency, d.specifiedVersion AS specified, d.resolvedVersion AS resolved
Zusätzliche Informationen
mappings.out
Die Datei mappings.out ermöglicht es Ihnen, die dem Knoten zugewiesene Artefakt-Typ auf Artefakte groupId zu customisieren, am häufigsten, um Artefakte, die von Ihrer Organisation erstellt wurden, speziell zu identifizieren.
Eingabe-Verzeichnis
Die Befehlszeilenoption für DependencyLoader
kann ein Verzeichnis sein, das mehrere Gradle Abhängigkeitsbäume enthält, die in dasselbe Neo4J-Datenbank entladen werden. Dies hilft bei der Analyse der Abhängigkeiten verwandter Projekte mit separaten build.gradle Dateien.
Begrenzt und Ausgelassen
Gradle identifiziert bestimmte Abhängigkeiten als Begrenzt und Ausgelassen. Derzeit werden diese nicht geladen, könnten jedoch leicht hinzugefügt werden, wahrscheinlich durch die Erstellung zusätzlicher Eigenschaften für die Beziehungen.
Source:
https://dzone.com/articles/understanding-dependenciesvisually