1. Gradleのソースセットとは?基本構造と主な役割
    1. ソースセットの定義と2つの標準ソースセット
    2. 既定のディレクトリ構成と出力先
    3. ソースセットが持つ主要プロパティ
  2. カスタムソースセットの作り方とJavaプロジェクトへの適用
    1. カスタムソースセットを作成する判断基準
    2. カスタムソースセットの基本設定手順
    3. srcDir()とsrcDirsの違いに注意
  3. Groovy・Scala・Kotlinとの併用におけるソースセット設定
    1. Groovyプラグインとの併用と共同コンパイル
    2. Scalaプラグインとの併用と注意点
    3. Kotlinプラグインとの併用
  4. Gradleでよくあるソースセット関連のエラーとその対処法
    1. カスタムソースセットからmainのコードを参照できない
    2. srcDirsによる意図しない既定ディレクトリの消失
    3. カスタムソースセットのテストが実行されない
  5. GradleツーリングAPIとビルドスクリプト移行時の注意点
    1. GradleツーリングAPIの役割とソースセット情報の取得
    2. Groovy DSLからKotlin DSLへの移行における注意点
    3. ソースセット移行時の検証ポイント
  6. まとめ
  7. よくある質問
    1. Q: Gradleのソースセットとは何ですか?
    2. Q: Gradleでカスタムソースセットを作成するにはどうすれば良いですか?
    3. Q: srcDir()とsrcDirsの違いは何ですか?
    4. Q: GradleではGroovyやScalaなど複数言語を併用できますか?
    5. Q: カスタムソースセットのテストを実行するにはどうすれば良いですか?

Gradleのソースセットとは?基本構造と主な役割

ソースセットの定義と2つの標準ソースセット

ソースセットとは、一連の論理的なソースファイルとリソースファイルの集まりです。GradleのJava Pluginを適用すると、デフォルトで「main」と「test」の2つのソースセットが自動的に作成されます。mainはアプリケーション本体の本番コード、testは単体テスト用のコードを格納する役割を持ちます。これにより、本番コードとテストコードを明確に分離して管理できます。

ソースセットにはJavaソースだけでなく、リソースファイルも含まれます。例えば設定ファイルやプロパティファイルなどは、Javaソースとは別のディレクトリに配置します。この分離構造により、コンパイル対象と実行時に必要なファイルを整理して扱えます。

既定のディレクトリ構成と出力先

Java Pluginの標準ディレクトリ構成は、以下のとおりです。

ソースセット ディレクトリ 用途
main src/main/java 本番Javaソース
main src/main/resources 本番リソース
test src/test/java テストJavaソース
test src/test/resources テスト用リソース

コンパイル済みクラスの出力先は、デフォルトでbuild/classes/java/<ソースセット名>です。リソースはbuild/resources/<ソースセット名>にコピーされます。この規則を知っておくと、ビルド結果の確認やトラブルシューティングが容易になります。

ソースセットが持つ主要プロパティ

ソースセットには、ビルド処理に必要なさまざまな情報がプロパティとして定義されています。主なものを以下に示します。

  • java:JavaソースのSourceDirectorySet。既定はsrc/<ソースセット名>/java
  • resources:リソース出力にコピーされる非Javaファイル。既定はsrc/<ソースセット名>/resources
  • allJava:ソースセット内の全Javaファイル(他言語プラグインが追加するJavaソースも含む)
  • output:コンパイル済みクラスや処理済みリソースの出力コレクション
  • compileClasspath:このソースセットのコンパイルに使用するクラスパス
  • runtimeClasspath:このソースセットの実行に使用するクラスパス

これらのプロパティは、カスタムソースセットを作成する際に、他のソースセットとの連携や依存関係の設定で使用します。

要点:ソースセットはmainとtestが標準で用意され、src/<ソースセット名>/javaとresourcesが既定ディレクトリです。カスタマイズの前にこの基本構造を理解することが重要です。

カスタムソースセットの作り方とJavaプロジェクトへの適用

カスタムソースセットを作成する判断基準

カスタムソースセットは、統合テスト(intTest)や特殊なコード生成など、標準のmain/testとは別に管理したいコードがある場合に作成します。Gradle公式ドキュメントでは、①独自のクラスパスでコンパイルする必要がある、②mainやtestとは異なる扱いのクラスを生成する、③プロジェクトの自然な一部である——このうち、③と①または②の両方に該当する場合にカスタムソースセットが適切としています。

例えば統合テストは、単体テストとは実行タイミングや依存ライブラリが異なるため、testソースセットとは分離するのが一般的です。逆に、単なるディレクトリ整理のためだけなら、既存ソースセットにsrcDir()で追加するほうがシンプルです。目的を明確にしてから導入を検討しましょう。

カスタムソースセットの基本設定手順

統合テスト用のintTestソースセットを作成する手順を、以下に示します。

  1. sourceSetsブロックでintTestソースセットを定義する
  2. mainソースセットの出力をintTestのcompileClasspathとruntimeClasspathに追加する
  3. configurationsブロックでintTestImplementationをtestImplementationから継承させる
  4. dependenciesブロックでintTest用の依存関係を宣言する
  5. intTest用のTestタスクを登録する

特に重要なのは2番目の手順です。ソースセットはデフォルトでは互いのコードを参照できないため、mainのコンパイル結果を明示的にクラスパスへ追加する必要があります。これを行わないと、統合テストから本番コードを呼び出せません。

srcDir()とsrcDirsの違いに注意

ソースディレクトリをカスタマイズする際、srcDir()メソッドとsrcDirsプロパティの挙動の違いを理解することが重要です。

操作 挙動 既存ディレクトリ
srcDir(‘path’) 既存ディレクトリに追加 維持される
srcDirs = [‘path’] 既定ディレクトリを置換 削除される

例えば、レガシープロジェクトで「src」を本番コードのディレクトリにしたい場合はsrcDirsで置換します。一方、既存のsrc/main/javaに加えてサードパーティのソースも含めたい場合はsrcDir()で追加します。誤って置換すると、標準ディレクトリが無効になりビルドエラーの原因になります。

要点:カスタムソースセットはmainの出力を明示的にクラスパスへ追加すること、Testタスクを自分で登録することが必須です。また、srcDir()は追加、srcDirsは置換という違いにも注意してください。

Groovy・Scala・Kotlinとの併用におけるソースセット設定

Groovyプラグインとの併用と共同コンパイル

Groovy Pluginを適用すると、既存のソースセットにgroovyプロパティ(GroovySourceDirectorySet)が追加されます。既定のGroovyソースディレクトリはsrc/<ソースセット名>/groovyです。例えばmainソースセットならsrc/main/groovy、testソースセットならsrc/test/groovyが使用されます。

Groovyの大きな特徴は、Javaとの共同コンパイル(joint compilation)に対応している点です。JavaコードとGroovyコードが相互に依存している場合でも、Groovyコンパイラが両方を同時に処理して解決できます。また、allJavaやallSourceプロパティには、Groovyソースディレクトリ内の.javaファイルも自動的に含まれます。これにより、既存のJavaプロジェクトにGroovyを段階的に導入できます。

Scalaプラグインとの併用と注意点

Scala Pluginを適用すると、ソースセットにscalaプロパティ(ScalaSourceDirectorySet)が追加されます。既定のScalaソースディレクトリはsrc/<ソースセット名>/scalaです。Scalaソースディレクトリには.scalaファイルと.javaファイルの両方を含められます。

ただし、Scalaの共同コンパイルはGroovyとは仕組みが異なります。ScalaコンパイラはJavaコンパイラを直接呼び出さず、まずScalaとJavaの型チェック用クラスファイルを生成し、その後JavaコンパイラがJavaソースをコンパイルする2段階のプロセスです。この違いにより、複雑な相互依存がある場合はビルド順序に注意が必要です。JavaとScalaの混在プロジェクトでは、この動作を理解したうえでソースディレクトリを設定しましょう。

Kotlinプラグインとの併用

Kotlin PluginはJavaベースのソースセットにKotlinソースディレクトリを追加します。既定ではsrc/<ソースセット名>/kotlinが使用されます。KotlinソースはJavaソースと同一プロジェクト内で共存可能です。JavaからKotlinを呼び出したり、KotlinからJavaを呼び出したりする相互運用が、追加設定なしで動作します。

なお、Kotlin Multiplatformでは階層構造のソースセット(hierarchical source sets)がサポートされていますが、これはKotlin Multiplatform固有の機能です。通常のJVMプロジェクトでKotlinを使用する場合は、Java Pluginのソースセット構造の上にKotlinソースディレクトリが追加されるという理解で十分です。各言語プラグインは、このように既存のソースセットを拡張する設計になっています。

要点:Groovy・Scala・Kotlinの各プラグインは、既存ソースセットに言語専用のソースディレクトリを追加します。Groovyはスムーズな共同コンパイル、Scalaは2段階コンパイルという違いを理解しておきましょう。

Gradleでよくあるソースセット関連のエラーとその対処法

カスタムソースセットからmainのコードを参照できない

カスタムソースセットを作成した直後に最もよく遭遇するのが、「シンボルを見つけられません」というコンパイルエラーです。これは、ソースセットがデフォルトで互いのコードを参照できないことが原因です。intTestソースセットからmainソースセットのクラスを呼び出すには、以下の設定が必要です。

  • intTestのcompileClasspathにmainのoutputを追加する
  • intTestのruntimeClasspathにmainのoutputを追加する

この設定を行わないと、統合テストのコンパイル時に本番コードのクラスが見つからずエラーになります。逆に、mainから別のソースセットを参照する場合も同様の設定が必要です。ソースセット間の依存関係は明示的に宣言するという原則を覚えておきましょう。

srcDirsによる意図しない既定ディレクトリの消失

ソースディレクトリをカスタマイズした際、突然「ソースファイルが見つからない」というエラーが発生することがあります。これは多くの場合、srcDirsプロパティへの代入によって既定ディレクトリが置換されてしまったことが原因です。

例えば、追加のつもりで「srcDirs = [‘thirdParty/src/main/java’]」と記述すると、src/main/javaが無効になります。既存ディレクトリを維持したまま追加するには、srcDir()メソッドを使用します。エラーが発生したら、まずbuild.gradleまたはbuild.gradle.ktsのソースセット設定を見直し、追加と置換のどちらの意図だったかを確認してください。この問題は、Gradleの設定に慣れていない開発者が特に陥りやすいポイントです。

カスタムソースセットのテストが実行されない

統合テスト用のソースセットを作成したのに、gradle testを実行してもテストが走らないという問題があります。これは、カスタムソースセットのテスト実行には、専用のTestタスクを自分で登録する必要があるためです。標準のtestタスクは、testソースセットしか対象にしません。

解決策として、intTestソースセット用のTestタスクを以下のように登録します。タスク内でtestClassesDirsにintTestの出力クラスディレクトリを、classpathにintTestのruntimeClasspathを指定します。これにより、gradle intTestというコマンドで統合テストを実行できるようになります。必要に応じて、buildタスクやcheckタスクに依存関係を追加して、ビルドプロセスに統合することも検討してください。

要点:よくあるエラーの原因は、ソースセット間の参照設定漏れ、srcDirsによる置換ミス、テストタスクの未登録の3つです。いずれも設定の見直しで解決できます。

GradleツーリングAPIとビルドスクリプト移行時の注意点

GradleツーリングAPIの役割とソースセット情報の取得

GradleツーリングAPIは、IDEや外部ツールがGradleビルドの情報をプログラム的に取得・操作するためのAPIです。IntelliJ IDEAやEclipseなどのIDEは、このAPIを通じてプロジェクトのソースセット構成や依存関係を読み取り、プロジェクトのインポートやコード補完に活用しています。ソースセットのディレクトリ構成を変更した場合、IDEとの連携にも影響があることを認識しておきましょう。

ツーリングAPIを使用すると、ソースセットのディレクトリ、コンパイルクラスパス、出力先などを外部から取得できます。ただし、ツーリングAPI自体の詳細な使用方法はGradle公式ドキュメントの「Gradle Tooling API」の章で確認する必要があります。本記事では、ビルドスクリプトの移行時にツーリングAPIとの互換性を意識することが重要という点に焦点を当てます。

Groovy DSLからKotlin DSLへの移行における注意点

ビルドスクリプトをGroovy DSL(build.gradle)からKotlin DSL(build.gradle.kts)へ移行する際、ソースセット設定の記述方法が変わります。代表的な違いを以下に示します。

操作 Groovy DSL Kotlin DSL
ディレクトリの置換 srcDirs = [‘src’] setSrcDirs(listOf(“src”))
ディレクトリの追加 srcDir ‘path’ srcDir(“path”)
依存関係の宣言 testImplementation ‘…’ testImplementation(“…”)

移行時は、文字列のクォート、メソッド呼び出しの括弧、プロパティ代入とメソッド呼び出しの区別に注意が必要です。Kotlin DSLは型安全性が高いため、誤った設定はコンパイル時に検出されやすくなります。移行後は、gradle tasksやgradle buildを実行して、ソースセットが正しく認識されているか確認してください。

ソースセット移行時の検証ポイント

ビルドスクリプトを移行した後は、以下の点を確認してソースセット設定が正しく引き継がれているか検証します。

  • カスタムソースセットのディレクトリ構成が意図どおりか
  • srcDir()による追加とsrcDirsによる置換が正しく変換されているか
  • ソースセット間のクラスパス依存関係(mainのoutput追加など)が維持されているか
  • カスタムTestタスクが正しく登録され、実行できるか

移行作業では、一度にすべてを変換するのではなく、段階的に移行して各段階でビルドを検証することが推奨されます。特に、ソースセットのカスタマイズが多いプロジェクトほど、設定の変換漏れが発生しやすくなります。移行後はIDEの再インポートも行い、ソースディレクトリが正しく認識されているか確認しましょう。

要点:ツーリングAPIはIDE連携に影響するため、ソースセット変更時は再インポートが必要です。DSL移行では追加と置換の区別を正確に変換し、段階的に検証しながら進めましょう。