#BASIC

[Gradle] Java Platform plugin

피치트리 2022. 2. 8. 13:14

[Goal]

Java Platform Plugin을 이해하고 BOM project를 만들어본다.

 

[Reference]

Java Platform

Maven BOM

 

What is Java Platform Plugin?

더보기

The Java Platform plugin brings the ability to declare platforms for the Java ecosystem. A platform can be used for different purposes:

  • a description of modules which are published together (and for example, share the same version)
  • a set of recommended versions for heterogeneous libraries. A typical example includes the Spring Boot BOM
  • sharing a set of dependency versions between subprojects

 Java Platform 플러그인은 자바 에코시스템을 위한 Platform을 선언할 수 있게 도와주는 플러그인입니다. 이 플러그인을 활용하면 여러 모듈에서 특정 버전의 라이브러리를 사용할 수 있도록 강제하는 기능을 제공할 수 있는데, Spring Boot BOM(Bill Of Materials) 프로젝트가 전형적인 예라고 생각하면 됩니다. Spring 개발자들이 라이브러리간의 의존성을 쉽게 사용할 수 있도록 편의를 제공하는 것이 Spring Boot인데요. 예를 들어 Spring 1버전에서는 A라이브러리 1.x버전, B라이브러리 2.x버전 등을 사용할 수 있도록 미리 정의해두어 개발자가 별도로 가장 적합한 버전의 라이브러리를 검토할 필요가 없게 됩니다. 이런 기능을 Java Platform 플러그인을 활용하여 만들 수 있습니다.

 

 간단하게 프로젝트를 하나 만들어서 테스트 해봅시다. java-platform이라는 gradle 프로젝트를 만들고, 하위에 platform과 app 모듈을 만들었습니다.

 

java-platform/build.gradle.kts

group = "org.example"
version = "1.0-SNAPSHOT"

allprojects {
    repositories {
        mavenCentral()
    }
}

java-platform/setting.gradle.kts 

rootProject.name = "java-platform"

include("app", "platform")

java-platform/platform/build.gradle.kts

plugins {
    `java-platform`
}

dependencies {
    constraints { // 중요!
        // Platform declares some versions of libraries used in subprojects
        api("commons-httpclient:commons-httpclient:3.1")
        runtime("org.apache.commons:commons-lang3:3.8.1")
    }
}

<Point1. constraints>

platform 프로젝트에서는 constraints로 라이브러리의 버전을 명시합니다. constraints는 dependencies와는 달라서 실제로 의존성이 추가되는 것은 아니며, 단지 추천 기능으로 제공된다고 합니다. 예를 들어 httpclient를 사용하지 않으면 상관이 없고, 사용하는데 constraints(ex. 3.1)와 상이한 버전(ex. 3.0)을 추가하면 3.1버전을 사용하게 되는 방식인거죠.

더보기

Note that this example makes use of constraints and not dependencies. In general, this is what you would like to do: constraints will only apply if such a component is added to the dependency graph, either directly or transitively. This means that all constraints listed in a platform would not add a dependency unless another component brings it in: they can be seen as recommendations.

<Point2. api와 runtime>

constraints는 api와 runtime 두 가지 방식으로 정의할 수 있습니다. api는 사용하는 쪽에서 compile과 runtime dependencies를 정의할 때 적용, runtime은 runtime dependencies를 정의할 때만 적용되는 차이가 있습니다. 

 

 

java-platform/app/build.gradle.kts

plugins {
    java
}

dependencies {
    implementation(platform(project(":platform"))) // platform 적용
    implementation("commons-httpclient:commons-httpclient")
    runtimeOnly("org.apache.commons:commons-lang3")
}

<Point1. platform>

위에서 정의한 platform 프로젝트를 'platform' 함수를 사용해 적용할 수 있습니다.

 

<Point2. 짚고 넘어갈 내용>

app 프로젝트에서는 implementation을 위해 java 플러그인을 추가했는데요. 공식문서에서 보면 java-platform 플러그인은 java 또는 java-library 플러그인과 함께 쓸 수 없다고 명시되어 있습니다. platform 프로젝트에는 해당 플러그인을 같이 쓸 수 없겠네요.

더보기

The java-platform plugin cannot be used in combination with the java or java-library plugins in a given project. Conceptually a project is either a platform, with no binaries, or produces binaries.

 

여기까지 간단하게 BOM 프로젝트를 만들어 보았습니다.

 

 

결과를 확인해보면 app프로젝트에서는 라이브러리의 버전을 명시하지 않았는데, httpclient와 commons-lang버전이 platform에서 정의한 버전임을 확인할 수 있었습니다. (다른 버전을 명시해도 platform버전을 따름)