階層化されたGradleのサブプロジェクトは、フルパスではなく一番最後に付く名前で区別される

こんにちは。 エキサイト株式会社の三浦です。

JavaでGradleを使っている場合、人によってはサブプロジェクトを使う場合もあるでしょう。

サブプロジェクトを使えばプロジェクトを整理しやすくなるためとても便利ですが、詰まりやすい点も存在します。

今回はその中の一つである、「サブプロジェクトはフルパスでは区別されない」という点を紹介します。

サブプロジェクトとは

Gradleでは「サブプロジェクト」というものを設定・使用することが出来ます。

setting.gradle

include ':application'
include ':sample1'
include ':sample2'

このように setting.gradle ファイルを設定した上で、

build.gradle

project(':application') {
    dependencies {
        implementation project(':sample1')
        implementation project(':sample2')
    }
}

このように build.gradle ファイルを設定すれば、 application というサブプロジェクトの中で、 sample1sample2 のサブプロジェクトを使用できます。

サブプロジェクト同士の依存関係を固定できたり、特定のサブプロジェクトでしか使用しないライブラリはそのサブプロジェクトのみにインストールされるようにするなど、プロジェクトを整理するのにとても便利な機能となっています。

フルパスが違うが同名のサブプロジェクトは区別されない

では次に、以下のようなサブプロジェクトを考えてみましょう。

setting.gradle

include ':application'
include ':sample1:example'
include ':sample2:example'

サブプロジェクトは、上記のように : で区切ることで階層構造のサブプロジェクトとして定義できます。

build.gradle

project(':application') {
    dependencies {
        implementation project(':sample1:example')
        implementation project(':sample2:example')
    }
}

今回は、 application の中で :sample1:example:sample2:example のサブプロジェクトを使うようにしてみました。

一見問題ないように見えるかもしれませんが、実はこれには大きな問題が存在します。

このようにすると、 :sample1:example:sample2:example のうち片方のサブプロジェクトしか読み込まれないのです。

どうやらGradleでサブプロジェクトを区別するときは、「フルパスではなく一番最後に付く名前」で区別されるようで、今回の場合だと両方とも example というサブプロジェクトとして判断されるので、片方しか読み込まれなくなってしまうようです。

一番最後に付く名前は違うものになるよう設定しましょう。

最後に

このような設定にしても、Gradleのビルド自体ではエラーが起きないため、問題に気づきにくくなってしまっています。

サブプロジェクトは便利な機能ですが、上記のような落とし穴もあるため、適切に使っていきましょう。