GradleにはResolutionStrategyというものがあり、バージョンのコンフリクト対応やモジュールの置き換えを行うことができます。
デフォルト
例として以下のように状態でmylibraryのokhttpのバージョンが低い場合です。
依存関係は以下のようになります。
+--- com.squareup.okhttp3:okhttp:3.10.0
| \--- com.squareup.okio:okio:1.14.0
\--- project :mylibrary
\--- com.squareup.okhttp3:okhttp:3.9.1 -> 3.10.0 (*)
mylibrary側のバージョンが変更されてapp側に合わせられてます。
appとmylibraryのバージョンを逆にした場合も同様に、低いほうが新しい方へ変更されます。
+--- com.squareup.okhttp3:okhttp:3.9.1 -> 3.10.0
| \--- com.squareup.okio:okio:1.14.0
\--- project :mylibrary
\--- com.squareup.okhttp3:okhttp:3.10.0 (*)
コンフリクトある場合はエラーにする
failOnVersionConflict()
によって、バージョンのコンフリクトが発生した場合はエラーが起きるようになります。
バージョンを強制する
force
によってバージョンを強制することができます。この場合、強制的に3.9.0にしています。
+--- com.squareup.okhttp3:okhttp:3.10.0 -> 3.9.0
| \--- com.squareup.okio:okio:1.13.0
\--- project :mylibrary
\--- com.squareup.okhttp3:okhttp:3.9.1 -> 3.9.0 (*)
これだけだとあまり意味ない感じですが、okhttpが依存してるokioに対してもバージョンを強制することができます。
このようにすると、okhttpが依存してるokioのバージョンを変更できます。
+--- com.squareup.okhttp3:okhttp:3.10.0
| \--- com.squareup.okio:okio:1.14.0 -> 1.12.0
\--- project :mylibrary
\--- com.squareup.okhttp3:okhttp:3.9.1 -> 3.10.0 (*)
すべての依存を列挙する
eachDependency
ですべての依存を取得することが可能です。依存ライブラリが更に別のライブラリに依存してるものも取得できます。
これを利用すると、以下のようにgroup単位でバージョンを強制することができます。
例としてhyperion-coreではsupportライブラリ27.1.0を使ってるのですが、これをすべて27.1.1に変更しています。
以下のようにバージョンが変更されます。長いので省略してますが、これをすべてforceで対応するには厳しいので、 eachDependency
を使うと便利です。
\--- com.willowtreeapps.hyperion:hyperion-core:0.9.21
+--- com.willowtreeapps.hyperion:hyperion-plugin:0.9.21
+--- com.android.support:appcompat-v7:27.1.0 -> 27.1.1
+--- com.android.support:recyclerview-v7:27.1.0 -> 27.1.1
モジュールを置き換える
dependencySubstitution
を使うと、外部モジュールとプロジェクト内モジュールを置き換えることが可能です。
例では、外部モジュールをプロジェクト内のモジュールに置き換えてます。
\--- com.star_zero:mylibrary:1.0.0 -> project :mylibrary
その逆もできます。
\--- project :mylibrary -> com.star_zero:mylibrary:1.0.0
また、外部モジュールを別の外部モジュールに置き換えることもできます。例として、Okioを別のバージョンに置き換えてます。forceに近い感じですね。
\--- com.squareup.okhttp3:okhttp:3.10.0
\--- com.squareup.okio:okio:1.14.0 -> 1.12.0
まとめ
依存ライブラリのバージョン等を制御したい場合は、こういった機能を使って解決していくと良いと思います。
DependencyHandler でも exclude
, force
, transitive
で個別に制御できるので、こちらも合わせてやってみると良いと思います。