Maven -> Gradle移行でライブラリのバージョンが意図せず変わった

目次
  1. 経緯
  2. 原因
  3. 適用されるバージョンを調べたい場合
  4. 適用するバージョンを明示的に指定したい場合
  5. 参考

Gradleあるあるだとは思いますが、先日ちょっとハマったことを書きます。

経緯

  • MavenからGradleに移行した際、とあるライブラリ(ここではライブラリAと呼称します)のバージョンが何故か上がっており、エラーによりアプリが動かなくなった。
    • build.gradle.ktsのdependenciesで指定するバージョンはpom.xmlと同じものを指定しており、意図的に上げるようなことはしていない。

原因

Gradleではバージョン違いの同じライブラリが競合した場合、基本的に新しい方のバージョンが適用されてしまう仕様があり、その影響によるものでした。

build.gradle.ktsのdependenciesに指定した別のライブラリBがライブラリAに依存しており、その依存しているライブラリAのバージョンが適用された結果、バージョンが上がってしまったようです。

↓公式ドキュメントの説明

https://docs.gradle.org/current/userguide/dependency_resolution.html#sec:version-conflict

Mavenの時は、依存関係の最短パスのバージョンを採用しようとするので、直接pom.xmlに記載していたライブラリAのバージョンが適用され、ライブラリBが依存するライブラリAは間接的に利用していたライブラリであったため適用されていなかったようです。

適用されるバージョンを調べたい場合

build.gradle.ktsだけからではライブラリの競合を判断できません。 その為、CUIから./gradlew -q dependencies を叩いて実際に適用されるバージョンを確認します。

大量に標準出力されるのでgrepなどして見たいライブラリ名で絞ってあげると良いと思います。

適用するバージョンを明示的に指定したい場合

strictly を指定してあげると強制的にバージョンを固定することができます。

バグ等でどうしても古いバージョンでライブラリを動かしたい場合はこの方法が使えそうです。

dependencies {
    implementation('hoge.fuga:hogefuga') {
        version {
            strictly '16.2.1'
        }
    }
    ...
}

https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html#sec:enforcing_dependency_version

参考

http://kkoudev.github.io/blog/2014/03/30/gradle-tips/