의존성 관리

의존성 관리 (Dependency Management)

Apache Pinot 프로젝트에서 외부 의존성을 관리하기 위한 지침을 다루는 문서예요. 지침을 적용함으로써 기여자가 코드베이스 전반에 걸쳐 의존성 관리 모범 사례를 일관되고 중앙화된 방식으로 계속 적용하도록 보장해요.

출처: 문서

본문

이 문서는 Apache Pinot 프로젝트에서 외부 의존성을 관리하기 위한 지침을 개요로 설명해요. 이 지침을 강제함으로써 기여자가 코드베이스 전반에 걸쳐 의존성 관리 모범 사례를 일관되고 중앙화된 방식으로 계속 적용하도록 보장할 수 있어요. 이러한 관행은 더 예측 가능한 의존성 그래프로 이어지며, OSS에 의존하는 서드파티 빌드가 컴플라이언스나 다른 이유로 필요에 따라 의존성을 반복적으로 오버라이드할 수 있게 해줘요. 동기에 대한 자세한 내용은 OSS 이슈를 보세요.

의존성 관리 지침 (Dependency Management Guidelines)

새 의존성을 추가하거나 기존 의존성의 버전을 업데이트할 때는 다음 지침을 따라요.

표준(비 플러그인) Pinot 하위 프로젝트의 경우:

  1. 모든 버전을 최상위 Pinot POM의 dependencyManagement 섹션 안에서 정의해요.
  2. 속성을 사용해 의존성 버전을 정의하고 Pinot POM에서 의존성을 선언할 때 그 속성을 참조해요. 이렇게 하면 Maven의 Versions 플러그인을 사용해 버전을 쉽게 오버라이드할 수 있어요.
  3. 하위 프로젝트의 dependencies 섹션 안에 의존성을 포함하되 버전은 정의하지 않아요.
  4. 의존성의 BOM 버전이 존재하면 BOM을 선호해서 의존성 그룹의 전이 의존성도 같은 버전으로 고정되게 해요. 예를 들어 Jackson 라이브러리의 모든 전이 의존성이 같은 버전에 있도록 com.fasterxml.jackson.core:jackson-annotations보다 com.fasterxml.jackson:jackson-bom을 선호해요.

Pinot 플러그인 하위 프로젝트의 경우:

  1. 필수 의존성(및 버전)이 Pinot POM에 있으면 의존성을 셰이드하지 말고 하위 프로젝트의 dependencies 섹션에서 버전 없이 참조해요.
  2. 의존성이 Pinot POM에 없거나 다른 버전으로 있으면 maven-shade-plugin을 사용해 라이브러리를 리로케이트해, Pinot POM이나 다른 플러그인의 중복 클래스로 인한 클래스 로딩 충돌을 피해요. 그런 경우 하위 프로젝트 POM 안에 의존성을 정의해 버전을 고정할 수도 있어요. 플러그인은 충돌하는 라이브러리를 참조하는 Pinot 메서드를 호출하지 않도록 보장해 런타임에 MethodNotFoundException으로 실패하지 않게 하는 책임이 있어요. 예를 들어 플러그인은 Jackson 라이브러리를 셰이드할 때 JsonUtils.objectToJsonNode는 호출하지 못하지만 JsonUtils.objectToString은 호출할 수 있을 거예요.

예시 (Examples)

Pinot POM에서 공유 의존성 관리

  <properties>
    <jackson.version>2.12.7</jackson.version>
    <snakeyaml.version>2.2</snakeyaml.version>
    ... 
  </properties>

  <dependencyManagement>
    <dependencies>
      <!-- prefer boms to pin multiple artifacts at the same version -->
      <dependency>
        <groupId>com.fasterxml.jackson</groupId>
        <artifactId>jackson-bom</artifactId>
        <version>${jackson.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>${snakeyaml.version}</version>
      </dependency>
      ...
  </dependencyManagement>

하위 프로젝트에서 공유 의존성 참조

  <dependencies>
    <!-- do not include a version with the dependency here
         as the version should be defined in the Pinot POM -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
    </dependency>
    ...
  </dependencies>

플러그인 하위 프로젝트에서 의존성 셰이딩

  <!-- pin versions required by plugin -->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>${aws.sdk.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  ...
  <!-- include required dependencies -->
  <dependencies>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>sdk-core</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>kinesis</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </dependency>
    ...
  </dependencies>
  ...

<!-- maven-shade-plugin configuration to relocate conflicting libraries -->
<relocations>
    <relocation>
      <pattern>software.amazon</pattern>
      <shadedPattern>${shade.prefix}.software.amazon</shadedPattern>
     </relocation>
    <relocation>
      <pattern>com.fasterxml.jackson</pattern>
      <shadedPattern>${shade.prefix}.com.fasterxml.jackson</shadedPattern>
     </relocation>
</relocations>

더 알아보기 (Learn more)