1. Background


Gradle 에서는 Compile, Runtime, Test 등 상황에 맞게 의존성(dependency)을 가져오도록 지원합니다.

이 때 가져오는 방식에 따라 방법이 다른데 그 부분을 이해하고자 이 글을 정리합니다.

2. Usage


아래 글은 claude의 도움을 받아 작성하였습니다. (95%는 클로드 + Grok 작성)

Implementation

  • 일반적으로 사용되는 방법

  • 모듈 내부에서만 사용되며, 다른 모듈에 노출되지 않는다.

  • API 은닉성이 좋아, 빌드 성능 향상

    라이브러리의 "내부 로직"에만 사용되거나, private 클래스에 쓰는 의존성입니다. 위 내용을 숨기면 클래스패스를 가볍게 하고, 내부 변경이 있어도 클라이언트가 재 컴파일 할 필요가 없습니다.

    라이브러리가 섞여 런타임에 에러가 발생할 수 있지만, 호환되는 버전이라면 에러가 나지 않을 수 있습니다 버전이 호환되면 문제 없습니다.

  • 라이브러리 버전이 충돌나면 높은 버전으로 설정됩니다.

API

  • 해당 모듈을 의존하는 다른 모듈에도 전이적으로 노출합니다.

  • 의존성이 변경되면 연쇄적으로 모든 하위 모듈 재컴파일 됩니다.

  • 라이브러리 모듈 개발 시에 외부에 노툴해야되는 의존성에 사용됩니다.

    라이브러리의 "외부" 인터페이스에 사용 라이브러리가 제공하는 클래스나 메서드의 시그니처, 다른 라이브러리의 타입을 사용한다면 그건 api로 선언해야됩니다. 왜냐하면 소비자가 내 라이브러리를 컴파일 할 때 그 타입을 "알아야" 합니다.

    컴파일 타임에 에러가 날 수 있는 상황은 A -> B -> C 에 의존하고 A -> C 에 의존할 때, 각각 의존하는 버전이 다르면 에러가 발생합니다.

    A -> B (1.0.0) -> C(1.0.0) A -> C (2.0.0) 이면, C (1.0.0 / 2.0.0)이 동시에 필요한 경우가 생겨 충돌됩니다.

compileOnly

  • 실제 APK/JAR에 포함되지 않습니다.
  • 주로 annotation processor나 제공된 환경의 라이브러리에 사용
  • Android provided와 유사합니다.

runtimeOnly

  • 컴파일 시에는 사용할 수 없음
  • 주로 로깅 구현체, JDBC 드라이버 등에 사용

testImplementation

  • 테스트 소스셋에서만 사용 가능
  • 프러덕션 코드에는 포함되지 않습니다.

annotationProcessor

  • 컴파일 클래스 패스에는 포함되지 않습니다.
  • Lombok, Dagger 등의 코드 생성 라이브러리에만 사용
    • 먼저 코드를 생성하고 추후에 컴파일됩니다.