Gradle에서 Dependency Pollution 문제 해결하기

지난번에 (Gradle dependency) api와 implementation 차이에 대해서 알아보았다.

이번에는 api와 implementation을 이용해 Dependency Pollution(의존성 오염) 문제와 해결하는 방법에 대해서 알아보자.

Dependency Pollution 이란

아래 그림과 같이 프로젝트 X가 있다. 프로젝트 X는 라이브러리 A와 B에 의존하고 있다. 또 다른 프로젝트 C는 프로젝트 X에 의존하고 있다.
diagram_1

이때, C는 X에 대한 의존성 갖게 되면서 A와 B에 대한 의존성 역시 갖게 된다. 이러한 상황을 C가 A와 B에 대해 의존성 전이(Transitive Dependency)를 갖는다고 한다.

이러한 의존성을 컴파일 타임에 사용할 수 있다고 생각해보자. X는 A와 B의 클래스들을 사용할 수 있을 것이고, C는 X뿐만 아니라 A와 B의 클래스 역시 사용할 수 있을 것이다.

이렇게 X의 의존성(A, B)이 C의 컴파일 타임시에 classpath에 노출되는 것을 Dependency Pollution이라고 한다.

Dependency Pollution 문제

Transitive Dependency로 인한 Dependency Pollution 문제를 갖고 있는 C에 어떤 영향이 있는지 알아보자.

C를 개발하고 있는 개발자가 라이브러리 A의 클래스를 사용하기로 결정할 수 있다. 하지만 개발자는 라이브러리 A에 대한 의존성이 X를 통해 추가되었음을 인지하지 못하고 사용할 수 있다.

X 개발자는 더 이상 라이브러리 A가 필요하지 않다고 결정하고 의존성에서 제거할 수 있다. 이 변경사항에 대해 X 개발자는 프로젝트 X가 제공하는 API에 대해서는 변경하지 않았기 때문에 minor한 업데이트로 간주할 것이다.

이후에 C 개발자가 X에 대한 버전을 업데이트(A가 제거된 버전)하는 경우에 C에서는 더 이상 라이브러리 A의 클래스를 사용할 수 없기 때문에 컴파일 에러가 발생한다.

결국, X의 컴파일 타임 의존성을 C의 컴파일 타임까지 전파하는 경우에 C 개발자는 원하지 않는 컴파일 타임 의존성을 갖게 될 수 있다.

Gradle의 해결 방법

Gradle을 사용하는 경우 종속성을 제어해 Dependency Pollution 문제를 줄일 수 있다.

방법은 간단한다. api대신 implementation을 사용하는 것이다.
diagram_2

X에서 A에 대한 종속성을 implementation을 이용해 선언하면 C는 더 이상 A에 대한 Transitive 컴파일 타임 종속성을 갖지 않게 된다. 따라서 C에서 실수로 A의 클래스를 사용할 수 없게 되는 것이다. 만약 C가 A의 클래스를 사용해야하는 경우에는 A에 대한 종속성을 명시적으로 선언해야한다.

반대로 특정 종속성을 컴파일 타임 종속성에 노출하고자하는 경우에는 implementation가 아닌 api를 사용하면 된다.

Gradle에서 Dependency Pollution 문제 해결하기

https://jongmin92.github.io/2019/12/07/Gradle/gradle-implementation/

Author

KimJongMin

Posted on

2019-12-07

Updated on

2021-03-22

Licensed under

댓글