mike-neckのブログ

Java or Groovy or Swift or Golang

Gradle で BOM を扱う

Spring の dependencyManagementPlugin は使わないで、これをやる方法。

f:id:mike_neck:20180811231620p:plain

なお、しおしおさんが調べてた…

siosio.hatenablog.com


とりあえず、手元で試してみる。

まず、BOMを書きます。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>test-bom</artifactId>
    <version>1</version>
    <packaging>pom</packaging>
    <name>test-bom</name>
    <description>bill of materials for test</description>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-engine</artifactId>
                <version>5.2.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

この BOM のグループは com.example で、 アーティファクト名が test-bom 、バージョンが 1 なので、 ~/.m2/repository/com/example/test-bom/1 ディレクトリーを作って、その下に test-bom-1.pom という名前で置いておく。

次の build.gradle を書いて、 BOM を取り込む

plugins {
  id 'java-library'
}
repositories {
  mavenCentral()
  mavenLocal()
}
dependencies {
  // bom
  testImplementation 'com.example:test-bom:1'

  // バージョン書かない
  testImplementation 'org.junit.jupiter:junit-jupiter-api'
  testRuntimeClasspath 'org.junit.jupiter:junit-jupiter-engine'
}

なお、これは Gradle 5.0 以降の機能のプレビューであるため、このままでは動かない。 settings.gradle に次の記述を追加する必要がある。

enableFeaturePreview('IMPROVED_POM_SUPPORT')

依存ライブラリーを確認してみる

$ ./gradlew dependencies --configuration=testImplementation

> Task :dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

testImplementation - Implementation only dependencies for source set 'test'. (n)
+--- com.example:test-bom:1 (n)
\--- org.junit.jupiter:junit-jupiter-api (n)

(n) - Not resolved (configuration is not meant to be resolved)

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
$ ./gradlew dependencies --configuration=testRuntimeClasspath

> Task :dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- com.example:test-bom:1
|    +--- org.junit.jupiter:junit-jupiter-api:5.2.0
|    |    +--- org.apiguardian:apiguardian-api:1.0.0
|    |    +--- org.opentest4j:opentest4j:1.1.0
|    |    \--- org.junit.platform:junit-platform-commons:1.2.0
|    |         \--- org.apiguardian:apiguardian-api:1.0.0
|    \--- org.junit.jupiter:junit-jupiter-engine:5.2.0
|         +--- org.apiguardian:apiguardian-api:1.0.0
|         +--- org.junit.platform:junit-platform-engine:1.2.0
|         |    +--- org.apiguardian:apiguardian-api:1.0.0
|         |    +--- org.junit.platform:junit-platform-commons:1.2.0 (*)
|         |    \--- org.opentest4j:opentest4j:1.1.0
|         \--- org.junit.jupiter:junit-jupiter-api:5.2.0 (*)
+--- org.junit.jupiter:junit-jupiter-api -> 5.2.0 (*)
\--- org.junit.jupiter:junit-jupiter-engine -> 5.2.0 (*)

(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

スコープを壊すことなく、ライブラリーが取り込めている模様