Base/CI, CD

Gradle 의존성 버전 관리

findmypiece 2021. 4. 7. 23:12
728x90

Gradle 에도 Maven 과 동일하게 dependencyManagement 를 사용할 수 있다. 

Maven과 동일하게 dependencyManagement 를 통해 의존성 버전을 명시하면 실제 의존성 정의시 버전을 명시하지 않아도 dependencyManagement에 명시된 버전이 자동으로 지정된다. 아래와 같이 사용하면 된다.

dependencyManagement {
  dependencies{
    dependency "com.google.guava:guava:17.0"
  }
}

dependencies {
  implementation 'com.google.guava:guava'
}

 

이를 통해 모듈간 의존성 버전을 관리할 수 있게 되는데 프로젝트 단위로 의존성 버전을 관리하려면 어떻게 해야 할까? Maven 에서는 pom.xml 만 존재하는 프로젝트를 만들어서 pom.xml에 dependencyManagement 만을 명시하고 packaging을 pom으로 해서 원격저장소에 deploy 한다. 그리고 각 프로젝트의 pom.xml 에서는 이를 parent로 지정해서 사용한다. 여기에서 dependencyManagement 만을 명시한 pom.xml 을 BOM(Bill of Materials) 파일이라고 부른다.

 

Gradle 에서는 어떻게 할까? 기본적으로 Gradle 에서도 위와 같이 Maven BOM 파일을 활용한다. 다만 BOM 프로젝트를 parent 로 지정하는 것이 아니라 dependencyManagement 에서 import 로 처리하거나 dependencies 에서 implementation 으로 처리하는 방법이 중 하나를 선택적으로 적용할 수 있다. 아래에서 org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE 이 BOM 파일이다.

dependencyManagement {
    // import a BOM
    imports {
        mavenBom "org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE"
    }
}

dependencies {
    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'
}
dependencies {
    // import a BOM
    implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')

    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'
}

위 두가지 방식은 모두 동일하게 동작한다. 그런데 아마도 dependencyManagement 에서 import 처리하는 방식은 과거 버전에서 사용되던 방식인데 유지되는 것 같고 장기적으로는 dependencies 에서 implementation 으로 처리하는 방법이 사용될 것 같다.

 

그런데 implementation 방식의 경우 Gradle 공식 메뉴얼을 보면 위에서 사용한 platform() 외에 enforcedPlatform() 라는 함수가 추가로 존재한다. 이것을 이해하기 위해서는 기본적으로 의존성을 추가할때 해당 의존성에 포함된 의존성도 함께 추가된다는 개념을 알아야 한다. SpringBoot의 Starter 의존성들을 예로 들면 Starter 의존성만 추가하면 그곳에 있는 모든 의존성을 프로젝트에서 사용할 수 있다.

 

enforcedPlatform() 를 사용해서 BOM파일을 추가하면 이렇게 다른 의존성에 의해 딸려오는 의존성의 버전도 강제로 변경할 수 있게 된다. 예를 들어 위 상황에서 임의의 의존성 A를 implementation 으로 추가했고 A 안에 groovy:2.5.14 가 포함되어 있더라도 enforcedPlatform() 에 의해 spring-boot-dependencies:1.5.8.RELEASE 에 포함된 groovy:1.8.6 이 해당 프로젝트에 추가되게 된다.

728x90