依存関係の理解…視覚的に!

挙手をしてください、ビルド自動化ツールが依存関係ツリーをどのように構築するかを本当に理解している人は何人いますか?今、自動化ツールを構築する仕事をしているから理解している人は手を下げてください。そうだったんですね!

ソフトウェアエンジニアの苛立ちを引き起こす責任の一つは、プロジェクトの依存関係を理解することです:どのような推移的な依存関係が導入され、誰によって導入されたのか;なぜv1.3.1が使用されているのかv1.2.10が宣言されているのか;推移的な依存関係が変更されたときに何が起こったのか;どのようにして同じアーティファクトの複数のバージョンが発生したのか?

各ソフトウェアエンジニアは、依存関係ツリーをテキストファイルにパイプし、特定のアーティファクトを検索し、その起源を特定するために戻ってきたことがあります。どれでも簡単ではないプロジェクトの場合、依存関係のメンタルマップを作成することは非常に困難であり、不可能である可能性があります。

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.

注意:これはグラフデータベースのチュートリアルではありませんし、グラフデータベースのバックグラウンドが必要ありません。興味があれば、Neo4Jにはチュートリアルホワイトペーパーがあります。

環境設定

Javaのインストール

Java 11以降が必要です。既にインストールされていない場合は、お気に入りのOpenJDKバージョンをインストールしてください。

Neo4Jをインストール

チュートリアルでは、依存関係情報がロードされるNeo4Jデータベースが必要です。共有されていない方が良いですが、ローダーは各実行前にデータベースをクリアするため注意が喚起されています!

Neo4Jは、このチュートリアルのような短期プロジェクトに適した個人用サンドボックスを提供しています。

あるいは、デスクトップやラップトップにNeo4Jをローカルにインストールしてください。HomebrewはMacOSのインストールを簡略化します。

Shell

 

brew install neo4j && brew services start neo4j

続行する前に、Neo4Jデータベースへのアクセスを確認してください。Neo4Jサンドボックスのリンクと資格情報を使用するか、またはローカルでhttp://localhost:7474で確認してください。ローカルインストールのデフォルトの資格情報はneo4j/neo4jです。ログインに成功すると、パスワードの変更が強制されます。

リポジトリをクローン

neo4j-gradle-dependencies リポジトリには、Neo4Jに依存関係をロードするためのものが含まれています。このチュートリアルでは、spring-boot の依存関係グラフを生成します。これらの2つのリポジトリをクローンする必要があります。

Shell

 

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

注意: ローカルのGradleは必要ありません。両方のリポジトリがGradleラッパーを使用しており、ラッパーが最初に使用される際に必要なすべてのコンポーネントをダウンロードします。

依存関係の生成

DependencyLoader は、Gradleによって生成された依存関係ツリーを入力として受け取ります。複数の設定(例えば、compileClasspathruntimeClasspathtestCompileClasspathtestRuntimeClasspath)を一緒にロードすることは可能ですが、チュートリアルでは単一の設定から始める方が操作が簡単です。

すべての設定の依存関係を生成するには:

  • gradle dependencies
  • ./gradlew dependencies

単一の設定の依存関係を生成するには:

  • gradle dependencies --configuration <configuration>
  • ./gradlew dependencies --configuration <configuration>

Spring Bootの依存関係を生成

このチュートリアルでは、Spring BootのcompileClasspath依存関係を使用してNeo4Jに依存関係グラフを作成します。リポジトリがクローンされたディレクトリから、以下のコマンドを実行してください:

Shell

 

Scott.Sosna@mymachine src% cd spring-boot/spring-boot-project/spring-boot
Scott.Sosna@mymachine spring-boot% ./gradlew dependencies --configuration compileClasspath > dependencies.out

ファイルdependencies.outには、Spring Bootのコンパイル時のclasspath依存関係が含まれています。

依存関係のロード

まず、DependencyLoader.java内の接続URLと認証資格情報を確認し、必要に応じて変更してください。

以下のコマンドを実行して、Spring Bootの依存関係をNeo4jにロードします。

Shell

 

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"

成功すると、gradleの出力は以下のようになります。

Shell

 

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

依存関係の表示

Neo4Jグラフを表示するための複数のツールが利用可能ですが、このチュートリアルには組み込みのブラウザツールで十分です。

完全なツリーの表示

MATCH(a) RETURN aクエリはSELECT * FROM <table>と同等の関係です。

アーティファクトの詳細の表示

見つかった各アーティファクトは、そのプロパティ(groupId/artifactId)とタイプを識別するノードを作成し、右側のペインに表示されます。

依存関係の詳細を表示

各依存関係は、依存関係の詳細を特定するプロパティ:設定、指定/バージョン、および設定を識別するリレーションシップとして作成されます。以下で選択された依存関係は、spring-security:spring-webio.micormeter:micrometer-observationに依存していることを示していますが、spring-webの指定バージョン1.10.7はバージョン1.11.0として解決されました。

依存関係をトラバース

Neo4Jを使用すると、ノードごとにグラフを探索できるため、ノードごとにグラフを手動で展開し、依存関係ツリーの特定の領域を探索する方法を提供します。

アーティファクトio.projectreactor.netty:reactor-netty-httpの依存関係を理解したいと仮定します。まず、その特定のノードに対してNeo4Jをクエリします。

Cypher

 

MATCH(a:Artifact {groupId: 'io.projectreactor.netty', artifactId: 'reactor-netty-http'}) RETURN a

ノードをダブルクリックすると、その隣接ノードが表示されます—依存しているアーティファクトと依存しているアーティファクト。

この展開されたグラフは、それに依存している1つのアーティファクト—アーティファクトタイプPROJECTのプロジェクトのルートと、それに依存している他の6つの依存関係を示しています。

次に、io.netty:netty-codehttps://github.com/netty/netty/tree/4.1/codec-httpc-httpをダブルクリックして、依存関係の次のレベルを表示してください。選択したノードの関係性(依存関係)に加えて、グラフ上に既に存在するノードに関する追加の関係性も表示されることに注意してください。

バージョン不一致の特定

Gradleの依存関係出力は、指定されたバージョンがGradleによって解決されたバージョンでなかった場合を示します。依存関係(関係)のプロパティは、表示される関係と添付されたアーティファクト(ノード)を制限するためにNeo4Jクエリで使用できます。

Cypher

 

MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURN a,b,d

必要に応じて、Neo4Jは表形式で結果を返すことができます。

Cypher

 

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

追加情報

mappings.out

mappings.outファイルを使用すると、アーティファクトのgroupIdに基づいてノードに割り当てられるアーティファクトタイプをカスタマイズできます。最も一般的には、あなたの組織によって作成されたアーティファクトを特定するために使用されます。

入力ディレクトリ

コマンドライン引数としてDependencyLoaderに指定できるのは、複数のGradle依存関係ツリーを同じNeo4Jデータベースにロードするためのディレクトリです。これにより、別々のbuild.gradleファイルを持つ関連プロジェクトの依存関係を理解するのに役立ちます。

制約と省略

Gradleは特定の依存関係を制約 および省略として識別します。現在、それらはロードされていませんが、関係性に対して追加のプロパティを作成することで簡単に含めることができます。

Source:
https://dzone.com/articles/understanding-dependenciesvisually