dependenciesの@aarの正体

build.gradleでしばしば見かけるこの記法

dependencies {
   implementation "jp.co.mst.android:awsome:1.0.0@aar"
}

この @aar という記法は アーティファクトオンリー記法 といい、以下に説明があります。

第51章 依存関係の管理

アーティファクトオンリー記法は、指定した拡張子のファイルのみをダウンロードする、というモジュール依存関係を作成します。ディスクリプタがあっても無視されます。

ライブラリの依存関係を無視する

例えば、 RxAndroidbuild.gradleを覗いてみますと

dependencies {
    api 'io.reactivex.rxjava2:rxjava:2.2.0'
    ...
}

とあるように、RxAndroidはRxJavaに依存しています。

なので、アプリからRxAndroidをgradleで取り込むと勝手にRxJavaがついて来るのですが、RxAndroidを取り込むときに以下のように @aar をつけると、RxAndroidのaarだけ持ってきて、RxJavaは取り込まれなくなります。

dependencies {
   implementation 'io.reactivex.rxjava2:rxandroid:2.1.0@aar'
}

何が嬉しいの?

あんまり積極的にお目にかかる機会もないとは思いますが、この記法のミソは

ディスクリプタがあっても無視されます。

というところでしょうか。

ディスクリプタというのは、mavenリポジトリ上で依存関係を管理するファイルで、RxAndroidの場合は rxandroid-2.1.0.pom がそれに当たります。

たとえば、何らかのとてつもない事情があってmavenリポジトリ上のディスクリプタが壊れてしまい、ライブラリの依存関係の解決ができなくなってしまったが、自分には治す権限がないけどaarだけ取り急ぎ使いたい!といったものすごく込み入った事情がある場合なんかには重宝されるかもしれません。

あるいは、ライセンス上取り込んじゃまずいライブラリの依存関係だけが何故か記述されてしまっているような罠に掛かりそうになったときなどにも使えるかもしれません。

実際には、多分 aarをローカルから読み込む - Learn to Live and Live to Learn などの記事にあるように、ローカルのパスからディスクリプタを使わないでaarを指定して取り込むときに使うことが大多数なのかなという気はしますが、社内リポジトリMaven Central Repository などで公開されているライブラリを @aar 付きで取り込んでるコードをどこかで見かけることがありましたら、そこには並々ならぬ事情があるのかもしれません。

アプリの依存関係とライブラリの依存関係がかぶってるときは@aarつけて取り込んだほうがいいの?

依存関係がかぶっていてライブラリのバージョンの競合が発生するような場合は、バージョンの競合を解決するための戦略が別途ありますので、@aar をつけることが最適な解決策になるケースは限られているでしょう(デフォルトではより新しいバージョンが採用されるようになってます)。

ちなみに、今回例に出したRxAndroidは、RxAndroidのバージョンによらず常に最新のRxJavaをアプリ側で取り込むことを推奨しています。

Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築

Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築