Help us understand the problem. What is going on with this article?

気をつけたいGradleの推移的依存関係とその解決

More than 3 years have passed since last update.

Gradleはライブラリの依存関係を上手に管理してくれるすぐれものですが、まれに突拍子もない不具合が発生する場合があります。しばらく前にGradleの推移的依存関係でハマったことがあったので、その具体的現象と原因、解決方法についてまとめておきました。

推移的依存関係とは?

Gradleのドキュメント読んでも、ほへー、位の感想なんで、こちらのサイトがわかりやすかったです。端的に言うと、複数のライブラリがあるライブラリ(A)に依存している場合、Aはバージョンが一番最新のものが適用されるということです。

なお推移的(transtive)とは言葉として??って感じでしたが、数学用語なんですね。wikipediaで説明を読むとなるほどなーという感じです。

具体的な事象

ある時、Pureeのバージョンアップ(3.3.0 -> 4.1.0)したところ、releaseのみビルドがfailしました。理由はPuree内で javax.annotation.ParametersAreNonnullByDefault が参照できないからとのこと。

/home/travis/build/project/testProject/app/src/main/java/com/testProject/test/log/OutBufferedLogcat.java:54: error: cannot find symbol @Nonnull
error: cannot access ParametersAreNonnullByDefault
  class file for javax.annotation.ParametersAreNonnullByDefault not found

ParametersAreNonnullByDefault から参照しているライブラリを確認すると、なぜか Crashlytics内のannotationを参照しています。Crashlyticsのannotationには ParametersAreNonnullByDefault がないため、エラーが発生しているというわけです。

Screen Shot 2015-12-11 at 18.36.43.png

なお以下がbuild.gradleの依存関係(抜粋)です。

build.gradle
dependencies {
    compile('com.crashlytics.sdk.android:crashlytics:2.5.0@aar') {
        transitive = true;
    }
    devCompile 'com.facebook.stetho:stetho:1.1.1'
    devCompile 'com.facebook.stetho:stetho-urlconnection:1.1.1'
    compile 'com.cookpad.puree:puree:4.1.1'
    configurations.all {
        resolutionStrategy.force 'com.android.support:support-annotations:23.0.1'
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.0'
    }
}

resolutionStrategyで support-annotationsfindbugについては強制的にバージョン適用されているとわかります。

原因

結論から言いますと、ReleaseビルドではGradleが推移的関係にあるライブラリを探した結果、 "該当するものあったけどちょっと違うやつだわー、ゴメン!" というエラーになっているということです。

依存関係は以下のコマンドで調べられます。

./gradlew :app:dependencies

gradleの:app:dependenciesを丹念に調べた結果、以下のことがわかりました。

  • javax.annotation.ParametersAreNonnullByDefaultcom.google.code.findbugs:jsr305:3.0.0 内のannotationが利用されている

  • releaseビルドにはcom.google.code.findbugs:jsr305:3.0.0 が入ってない。理由としては

    • Release以外の場合はStethoを導入している。Stethoは内部的に com.google.code.findbugs:jsr305:3.0.0 に依存しているため、推移的依存が適用されてjavax.annotation.ParametersAreNonnullByDefaultが参照できる。
dependencies
+--- com.facebook.stetho:stetho:1.1.1
|    +--- commons-cli:commons-cli:1.2
|    \--- com.google.code.findbugs:jsr305:2.0.1 -> 3.0.0
+--- com.facebook.stetho:stetho-urlconnection:1.1.1
|    \--- com.google.code.findbugs:jsr305:2.0.1 -> 3.0.0
  • build.gradle内ではconfigurations.allでcom.google.code.findbugsのversionの強制が設定されているものの、compileには入ってないため、Releaseにはjavax.annotationが入っていないです。
build.gradle
configurations.all {
    resolutionStrategy.force 'com.android.support:support-annotations:23.0.1'
    resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.0'
}
  • com.google.code.findbugsが入っていないReleaseビルドは推移的依存性によりCrashlyticsにあるannotation配下が参照されます。結果、そこにはjavax.annotation.ParametersAreNonnullByDefaultがないのでエラーになります。

解決策

compile 'com.google.code.findbugs:jsr305:3.0.0' をdependenciesに追加すれば、依存するバージョンが正しくなり、javax.annotation.ParametersAreNonnullByDefaultが参照されるようになりました。

まとめ

わけのわからない依存関係のエラーがでた場合は、

  • なにはともあれdependencies treeで丹念に依存状況とバージョンを確認する
  • 場合によってはライブラリを追加、あるいはライブラリから推移的依存関係となってしまうライブラリをexcludeする

ことをオススメします。

tomoima525
カレー大好き。気になることは美味しいカレーのスパイス調合度合いですね。スパイスだけで言うとカレー屋エチオピアが至高。うまみとかで総合するとヤミツキが横綱。具だくさんチキンカレートマトパクチートッピング。ついでchaoカリーのベーコンエッグ野菜カレー。原点は鎌倉のキャラウェイのチーズカレー。 メーヤウも捨てがたい。ポークカレー派です。アジア系カレー好きかも。メルカリではAndroidエンジニアです。
http://tomoima525.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした