손들어보세요, 우리 중 몇 명이나 정말로 빌드 자동화 도구가 의존성 트리를 어떻게 구축하는지 이해하고 있나요? 이제 빌드 자동화 도구를 개발하는 일을 하고 있기 때문에 이해하는 사람은 손을 내려놓으세요. 그랬죠!
소프트웨어 엔지니어들에게 가장 답답한 책임 중 하나는 프로젝트의 의존성을 이해하는 것입니다: 누가 어떤 전이적 의존성을 가져왔는지; 왜 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 11 이상이 필요합니다. 이미 설치되어 있지 않다면, 즐겨찾는 OpenJDK 버전을 설치하세요.
Neo4J 설치
이 튜토리얼에는 의존성 정보가 로드될 Neo4J 데이터베이스가 필요하며, 최선은 공유되지 않은 것이어야 합니다. 로더는 매 실행 전에 데이터베이스를 초기화합니다.경고를 받았습니다!
Neo4J는 이러한 튜토리얼과 같은 단기 프로젝트에 적합한 개인 샌드박스를 제공합니다.
또는 데스크톱이나 노트북에 Neo4J를 로컬로 설치하십시오. Homebrew는 MacOS 설치를 간소화합니다:
brew install neo4j && brew services start neo4j
계속하기 전에, Neo4J 데이터베이스에 대한 접근을 확인하세요. 브라우저를 사용하여 Neo4J 샌드박스의 링크와 자격 증명을 사용하거나, 로컬에서 http://localhost:7474에 접속하세요. 로컬 설치의 기본 자격 증명은 neo4j/neo4j입니다; 로그인 성공 시, 비밀번호를 변경하도록 강제됩니다.
저장소 복제
neo4j-gradle-dependencies 저장소에는 Neo4J에 의존성을 로드하기 위한 것들이 포함되어 있습니다. 이 튜토리얼에서는 스프링 부트의 의존성 그래프를 생성합니다. 이 두 저장소를 복제해야 합니다.
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 Wrapper를 사용하므로, 래퍼가 처음 사용될 때 필요한 모든 구성 요소를 다운로드합니다.
의존성 생성
DependencyLoader
는 Gradle에 의해 생성된 의존성 트리를 입력으로 사용합니다. 여러 구성을 동시에 로드할 수 있으나 — 즉, compileClasspath
, runtimeClasspath
, testCompileClasspath
, testRuntimeClasspath
— 튜토리얼의 경우 단일 구성으로 시작하는 것이 훨씬 더 쉽게 탐색할 수 있습니다.
모든 구성에 대한 의존성을 생성하려면:
gradle dependencies
./gradlew dependencies
단일 구성에 대한 의존성을 생성하려면
gradle dependencies --configuration <configuration>
./gradlew dependencies --configuration <configuration>
스프링 부트 의존성 생성
이 튜토리얼은 스프링 부트의 compileClasspath
의존성을 사용하여 Neo4J에서 의존성 그래프를 생성합니다. 저장소가 복제된 디렉토리에서 다음 명령을 실행하십시오:
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
는 스프링 부트의 컴파일 타임 클래스패스 의존성을 포함합니다.
의존성 로드
먼저 DependencyLoader.java에서 연결 URL과 인증 자격 증명을 확인하고 필요한 경우 수정하십시오.
다음 명령을 실행하여 스프링 부트 의존성을 Neo4j에 로드하십시오:
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"
성공하면 그레이들의 출력 라인은 다음과 같습니다:
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-web가 io.micrometer:micrometer-observation에 의존하지만, spring-web의 지정된 버전 1.10.7이 버전 1.11.0으로 해결되었습니다.
의존성 탐색
Neo4J를 사용하면 노드별로 그래프를 탐색할 수 있으며, 노드별로 그래프를 수동으로 확장하여 의존성 트리의 특정 영역을 탐색하는 방법을 제공합니다.
아티팩트 io.projectreactor.netty:reactor-netty-http의 의존성을 이해하려고 가정합니다. 먼저 해당 특정 노드에 대해 Neo4J를 쿼리합니다.
MATCH(a:Artifact {groupId: 'io.projectreactor.netty', artifactId: 'reactor-netty-http'}) RETURN a
노드를 더블 클릭하면 해당 노드에 의존하는 아티팩트와 그 노드가 의존하는 아티팩트의 이웃 노드가 표시됩니다.
이 확장된 그래프는 해당 아티팩트에 의존하는 하나의 아티팩트인 프로젝트의 루트를 보여주며, 아티팩트 유형이 PROJECT이고 그 아티팩트가 의존하는 다른 6개의 의존성을 보여줍니다.
다음으로, io.netty:netty-code https://github.com/netty/netty/tree/4.1/codec-httpc-http를 더블클릭하여 종속성의 다음 수준을 표시합니다. 선택한 노드의 관계(종속성) 외에도 이미 그래프에 있는 노드에 대한 추가 관계가 표시될 수 있음에 유의하세요.
버전 불일치 식별
Gradle의 종속성 출력은 지정된 버전이 Gradle에 의해 해결된 버전이 아닌 경우를 나타냅니다. 종속성(관계)의 속성은 Neo4J 쿼리에서 사용될 수 있으며, 표시되는 관계와 연결된 아티팩트(노드)를 제한할 수 있습니다.
MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURN a,b,d
필요한 경우 Neo4J는 결과를 테이블 형식으로 반환하여 더 쉽게 검토할 수 있습니다.
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를 기반으로 노드에 할당된 아티팩트 유형을 사용자 지정할 수 있으며, 대개 조직에 의해 생성된 아티팩트를 구체적으로 식별하는 데 사용됩니다.
입력 디렉토리
디렉토리에 여러 Gradle 의존성 트리가 동일한 Neo4J 데이터베이스에 로드되는 것을 지정하는 DependencyLoader
의 명령줄 인수는 build.gradle 파일을 가진 관련 프로젝트의 의존성을 이해하는 데 도움이 됩니다.
Gradle은 특정 의존성을 Constrained 및 Omitted로 식별합니다. 현재 이러한 의존성은 로드되지 않으나, 관련 관계에 대한 추가 속성을 생성함으로써 쉽게 포함시킬 수 있습니다.
Source:
https://dzone.com/articles/understanding-dependenciesvisually