build.gradleとは、Gradle(グレイドル)というビルドツールに「どのプラグインを使い、どこから何のライブラリを取り込み、どんなタスクを実行するか」を指示する設定ファイルです。 書き方には、Groovy言語で書く build.gradle(Groovy DSL)と、Kotlin言語で書く build.gradle.kts(Kotlin DSL)の2種類があります。

この記事では、同じ設定をGroovy DSLとKotlin DSLで並べた対訳表、implementation や api などの依存設定の判断表、コマンド早見表をまとめました。さらに、外部ライブラリなしのマルチモジュール構成(app+lib)を Gradle 8.14.3 で実際にビルドし、出力をそのまま掲載しています。最新版は Gradle 9.8.0(2026年9月29日リリース) で、9系の主な変更点も公式リリースノートで確認しました。

build.gradleの書き方早見表(Groovy DSL / Kotlin DSL 対訳)

やりたいこと Groovy DSL(build.gradle) Kotlin DSL(build.gradle.kts)
プラグインを使う id 'java-library' `java-library` または id("java-library")
外部プラグイン(版指定) id 'org.example.x' version '1.0' id("org.example.x") version "1.0"
リポジトリ指定 mavenCentral() mavenCentral()
依存を追加 implementation 'g:a:1.0' implementation("g:a:1.0")
別モジュールに依存 implementation project(':lib') implementation(project(":lib"))
BOMで版をそろえる implementation platform('g:bom:1.0') implementation(platform("g:bom:1.0"))
Javaのバージョン languageVersion = JavaLanguageVersion.of(21) languageVersion = JavaLanguageVersion.of(21)
メインクラス mainClass = 'com.example.Main' mainClass = "com.example.Main"
追加プロパティ ext.greeting = 'Hi' val greeting by extra("Hi")
タスクを登録 tasks.register('hello') { ... } tasks.register("hello") { ... }
既存タスクを設定 tasks.named('test') { useJUnitPlatform() } tasks.named<Test>("test") { useJUnitPlatform() }
型ごとに一括設定 tasks.withType(JavaCompile) { ... } tasks.withType<JavaCompile> { ... }
文字列 '...' も "..." も可 "..." のみ
変数 def x = 1 val x = 1
モジュール一覧(settings) include 'app', 'lib' include("app", "lib")

迷ったら、新規作成はKotlin DSLがおすすめです。 gradle init の既定もKotlin DSLで、IDEの補完と型チェックが効くため、書き間違いをビルド前に見つけやすくなります。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「build.gradle書き方|Groovy/Kotlin DSL対訳と依存設定一覧」

Gradleの最新版と9系の主な変更点

2026年10月時点の最新版は Gradle 9.8.0(2026年9月29日リリース)です。 9.8.0ではデーモンとツールチェーンの両方でJava 27に対応しました。9系の大きな変更は、2025年7月31日リリースの 9.0.0 に集まっています。

項目 Gradle 8系 Gradle 9系
Gradle本体を動かすJava Java 8以上 Java 17以上
コンパイル・テスト対象のJava Java 8以上 Java 8以上(ツールチェーンで指定)
Kotlin DSLのKotlin 2.0系 2.2系
Groovy DSLのGroovy 3.0系 4.0系
Configuration Cache 任意機能 推奨の実行モード(未対応時は従来モードへ自動で切り替え)
バージョン表記 8.5 など SemVer(9.0.0 のように3桁)
アーカイブ(jar/zip) ― 既定で再現可能な出力(同じ入力なら同じバイナリ)

8系から上げるときは、まず8系の最新でビルドし、非推奨(deprecation)警告をなくしてから9系へ上げると、移行がスムーズです。警告は --warning-mode all を付けると一覧で出ます。

./gradlew build --warning-mode all
./gradlew wrapper --gradle-version 9.8.0   # Wrapperの版を上げる

実行して確かめる:マルチモジュールのビルド(app+lib)

ここからは、外部ライブラリを使わないマルチモジュール構成を実際にビルドします。lib が計算用のクラスを持ち、app がそれを呼び出す構成です。

  • 実行環境:Gradle 8.14.3 / OpenJDK 21.0.10 / Linux
  • --offline(ネットワークを使わない)で実行

ファイル構成

todo-sample/
├── settings.gradle.kts
├── gradle/
│   └── libs.versions.toml
├── app/
│   ├── build.gradle.kts
│   └── src/main/java/com/example/app/Main.java
└── lib/
    ├── build.gradle.kts
    └── src/main/java/com/example/lib/TaskCounter.java

settings.gradle.kts

rootProject.name = "todo-sample"
include("app", "lib")

settings.gradle(.kts) は「どのフォルダがモジュールか」を決めるファイルです。 ここに書かれていないフォルダは、build.gradleがあってもビルド対象になりません。

gradle/libs.versions.toml(バージョンカタログ)

[versions]
java = "21"
junit = "5.13.4"

[libraries]
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }

lib/build.gradle.kts

plugins {
    `java-library`
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(libs.versions.java.get().toInt())
    }
}

app/build.gradle.kts

plugins {
    application
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(libs.versions.java.get().toInt())
    }
}

dependencies {
    implementation(project(":lib"))
}

application {
    mainClass = "com.example.app.Main"
}

val greeting by extra("Hello Gradle")

tasks.register("hello") {
    group = "sample"
    description = "あいさつを表示します"
    val msg = greeting
    doLast {
        println("$msg from ${project.name}")
    }
}

tasks.named<JavaExec>("run") {
    jvmArgs("-Dstdout.encoding=UTF-8")
}

Javaのソース

// lib/src/main/java/com/example/lib/TaskCounter.java
package com.example.lib;

import java.util.List;

public class TaskCounter {
    public long countDone(List<String> statuses) {
        return statuses.stream().filter("done"::equals).count();
    }
}
// app/src/main/java/com/example/app/Main.java
package com.example.app;

import com.example.lib.TaskCounter;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        var statuses = List.of("done", "todo", "done", "doing");
        long done = new TaskCounter().countDone(statuses);
        System.out.println("完了タスク: " + done + " / " + statuses.size());
    }
}

実行結果:gradle build

$ gradle --offline build --console=plain
> Task :lib:compileJava
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :lib:processResources NO-SOURCE
> Task :lib:classes
> Task :lib:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava NO-SOURCE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test NO-SOURCE
> Task :app:check UP-TO-DATE
> Task :app:build
> Task :lib:assemble
> Task :lib:compileTestJava NO-SOURCE
> Task :lib:processTestResources NO-SOURCE
> Task :lib:testClasses UP-TO-DATE
> Task :lib:test NO-SOURCE
> Task :lib:check UP-TO-DATE
> Task :lib:build

BUILD SUCCESSFUL in 8s
7 actionable tasks: 7 executed

:lib:compileJava が :app:compileJava より先に動いている点に注目してください。implementation(project(":lib")) と書いたことで、Gradleが依存関係から実行順を自動で決めています。NO-SOURCE は「対象ファイルがないので飛ばした」という意味で、エラーではありません。

成果物は次のとおりです。

$ ls app/build/libs lib/build/libs app/build/distributions
app/build/distributions:
app.tar
app.zip

app/build/libs:
app.jar

lib/build/libs:
lib.jar

実行結果:run・独自タスク・依存ツリー

$ gradle --offline -q :app:run
完了タスク: 2 / 4

$ gradle --offline -q :app:hello
Hello Gradle from app

$ gradle --offline -q :app:dependencies --configuration runtimeClasspath

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

runtimeClasspath - Runtime classpath of source set 'main'.
\--- project :lib

実行結果:2回目のビルドは UP-TO-DATE

$ gradle --offline build -x test --console=plain
> Task :lib:compileJava UP-TO-DATE
> Task :app:compileJava UP-TO-DATE
...
BUILD SUCCESSFUL in 1s
7 actionable tasks: 7 up-to-date

入力(ソースや設定)が変わっていないタスクは UP-TO-DATE になり、再実行されません。 初回8秒が2回目は1秒になりました。これがGradleの「インクリメンタルビルド」です。

同じ内容のGroovy DSL版(動作確認済み)

同じ構成をGroovy DSLでも書き、ビルドと run・hello が同じ結果になることを確認しました。

// settings.gradle
rootProject.name = 'todo-sample-groovy'
include 'app', 'lib'
// app/build.gradle
plugins {
    id 'application'
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(libs.versions.java.get() as int)
    }
}

dependencies {
    implementation project(':lib')
}

application {
    mainClass = 'com.example.app.Main'
}

ext.greeting = 'Hello Gradle'

tasks.register('hello') {
    group = 'sample'
    description = 'あいさつを表示します'
    def msg = greeting
    doLast {
        println "$msg from ${project.name}"
    }
}

tasks.named('run', JavaExec) {
    jvmArgs '-Dstdout.encoding=UTF-8'
}
$ gradle --offline -q :app:run
完了タスク: 2 / 4
$ gradle --offline -q :app:hello
Hello Gradle from app

Groovy DSLは括弧や型を省略でき、Kotlin DSLは括弧・ダブルクォート・型が必要、という違いが対訳でよくわかります。

依存設定の一覧と選び方(implementation / api / compileOnly …)

dependencies { } の中で使う言葉(コンフィグレーション)は、「いつ必要か(コンパイル時/実行時/テスト時)」と「依存先に見せるか」で選びます。

設定 コンパイル時 実行時 利用側に伝わる 主な使いどころ
implementation 使える 含まれる コンパイル時は伝わらない ふつうの依存はこれ
api 使える 含まれる 伝わる ライブラリの公開メソッドの引数・戻り値に出る型(java-library プラグインが必要)
compileOnly 使える 含まれない 伝わらない 実行環境が用意するAPI、アノテーションだけのライブラリ
runtimeOnly 使えない 含まれる 実行時のみ JDBCドライバ、ログの実装など
testImplementation テストで使える テストで含まれる ― JUnit、AssertJなど
testRuntimeOnly 使えない テストで含まれる ― junit-platform-launcher など
annotationProcessor 処理に使う 含まれない ― Lombok、MapStructなどのコード生成
testAnnotationProcessor テストの処理に使う 含まれない ― テストコードでLombokを使う場合

どれを選ぶかの判断表

質問 はい いいえ
① テストでしか使わない? testImplementation(実行時だけなら testRuntimeOnly) ②へ
② ソースコードで import する? ③へ runtimeOnly
③ 実行時は環境が用意してくれる? compileOnly ④へ
④ 自作ライブラリの公開APIの型として外に見せる? api implementation

api を増やすと、そのライブラリを変えたときに利用側も再コンパイルが必要になります。 まず implementation にしておき、利用側で「型が見つからない」と言われたものだけ api にすると、ビルドが速く保てます。

Lombokのようなコード生成ライブラリは2行セットで書きます。

dependencies {
    compileOnly("org.projectlombok:lombok:1.18.42")
    annotationProcessor("org.projectlombok:lombok:1.18.42")
}

compile / testCompile / runtime は、古い資料に出てくる設定名です。Gradle 7.0で削除されているため、現在は上の表の名前に置き換えて書きます。

よく使うGradleコマンド・タスク早見表

Wrapper(./gradlew)があるときは、gradle ではなく ./gradlew を使います。 Windowsは gradlew.bat(PowerShellでは .\gradlew)です。

やりたいこと コマンド
コンパイル+テスト+jar作成 ./gradlew build
テストだけ ./gradlew test
1クラスだけテスト ./gradlew test --tests "com.example.TaskCounterTest"
成果物を消す ./gradlew clean
きれいにしてビルド ./gradlew clean build
テストを飛ばしてビルド ./gradlew build -x test
アプリを実行(application) ./gradlew run
特定モジュールだけ ./gradlew :app:build
依存ツリーを見る ./gradlew :app:dependencies --configuration runtimeClasspath
ある依存がなぜ入ったか ./gradlew :app:dependencyInsight --dependency 名前
タスク一覧 ./gradlew tasks(全部は tasks --all)
タスクの詳細 ./gradlew help --task test
ネットを使わない ./gradlew build --offline
依存を取り直す ./gradlew build --refresh-dependencies
ファイル変更で自動再実行 ./gradlew test --continuous(-t)
エラーの詳細 --stacktrace / --info / --debug
非推奨の警告を全部表示 --warning-mode all
並列ビルド --parallel
ビルドキャッシュ --build-cache
Configuration Cache --configuration-cache
プロパティを渡す -Penv=dev(スクリプトでは findProperty("env"))
出力を減らす/平文で出す -q / --console=plain
デーモンを止める ./gradlew --stop

よく使う設定は gradle.properties に書いておくと、毎回オプションを付けずに済みます。

# gradle.properties(プロジェクト直下)
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8

タスク同士の関係(Javaプラグイン)

flowchart LR
  compileJava --> classes --> jar --> assemble --> build
  classes --> compileTestJava --> testClasses --> test --> check --> build
  clean

build は assemble(成果物作成)と check(テスト)をまとめたタスクです。 だから build -x test で test を除外できます。

Gradle Wrapperの使い方

Wrapperとは、プロジェクトごとにGradleのバージョンを固定し、Gradle未インストールのPCでも同じ版でビルドできるようにする仕組みです。

# 作成(Gradle本体がある環境で1回だけ)
gradle wrapper --gradle-version 8.14.3

# 版を上げる
./gradlew wrapper --gradle-version 9.8.0

実際に作成すると、次のファイルができます。

$ gradle --offline wrapper --gradle-version 8.14.3
> Task :wrapper

BUILD SUCCESSFUL in 19s
1 actionable task: 1 executed

$ ls
app  gradle  gradlew  gradlew.bat  lib  settings.gradle.kts
$ ls gradle/wrapper
gradle-wrapper.jar
gradle-wrapper.properties
$ cat gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
ファイル 役割 Gitに入れる?
gradlew / gradlew.bat 起動スクリプト 入れる
gradle/wrapper/gradle-wrapper.jar ダウンロード用の小さなjar 入れる
gradle/wrapper/gradle-wrapper.properties 使う版とURL 入れる
.gradle/、build/ キャッシュ・成果物 入れない(.gitignoreへ)

./gradlew の初回は distributionUrl からGradle本体をダウンロードします。 今回の検証環境は外部への接続が制限されているため、初回ダウンロードで次のエラーになりました。社内プロキシの内側などで同じ状況になったときは、gradle.properties に systemProp.https.proxyHost を設定するか、distributionUrl を社内ミラーに向けると解決します。

$ ./gradlew --offline build
Downloading https://services.gradle.org/distributions/gradle-8.14.3-bin.zip

Exception in thread "main" java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 403 Forbidden"

--offline はライブラリ取得のための設定で、Wrapperが本体をダウンロードする処理には効きません。そのため、以降の検証はインストール済みの gradle コマンドで行っています。

バージョンカタログ(libs.versions.toml)の書き方

バージョンカタログとは、ライブラリ名とバージョンを gradle/libs.versions.toml にまとめ、各build.gradleから libs.〜 で参照する仕組みです。 モジュールが増えても、版の更新は1か所で済みます。

[versions]
java = "21"
junit = "5.13.4"

[libraries]
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }
junit-launcher = { module = "org.junit.platform:junit-platform-launcher" }

[bundles]
test = ["junit-jupiter"]

[plugins]
# 例:外部プラグインの版もここで管理できる
# spotless = { id = "com.diffplug.spotless", version = "8.0.0" }
tomlのセクション 書き方 build.gradle.kts での参照
[versions] java = "21" libs.versions.java.get()
[libraries] junit-jupiter = { module = "g:a", version.ref = "junit" } libs.junit.jupiter
[bundles] test = ["junit-jupiter"] libs.bundles.test
[plugins] x = { id = "...", version = "..." } alias(libs.plugins.x)

名前の - は . に変わります(junit-jupiter → libs.junit.jupiter)。テスト依存は次のように書きます。

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(platform(libs.junit.bom))
    testImplementation(libs.junit.jupiter)
    testRuntimeOnly(libs.junit.launcher)
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

platform(...) でBOMを読み込むと、BOMに含まれるライブラリはバージョンを省略できます。 上の junit-jupiter に版がないのはこのためです。

よくあるエラーと対処(実際のエラー文つき)

1. Cannot resolve external dependency ... because no repositories are defined.

repositories { } を書かずに外部ライブラリを追加したときのエラーです(実行結果)。

* What went wrong:
Execution failed for task ':lib:compileTestJava'.
> Could not resolve all files for configuration ':lib:testCompileClasspath'.
   > Cannot resolve external dependency org.junit:junit-bom:5.13.4 because no repositories are defined.
     Required by:
         project :lib

→ repositories { mavenCentral() } を追加します。 マルチモジュールでは、settings.gradle.kts にまとめて書く方法もあります。

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

2. No cached version of ... available for offline mode.

--offline のまま、まだ一度もダウンロードしていないライブラリを使ったときのエラーです(実行結果)。

   > Could not resolve org.junit:junit-bom:5.13.4.
     Required by:
         project :lib
      > No cached version of org.junit:junit-bom:5.13.4 available for offline mode.

→ ネットにつながる状態で --offline を外して1回ビルドし、キャッシュ(~/.gradle/caches)に入れます。 社内ネットワークでは、プロキシ設定やミラーリポジトリの指定も確認します。

3. Kotlin DSLにGroovyの書き方を混ぜた(Unresolved reference)

build.gradle.kts に implementation project(":lib") と括弧なしで書いたときのエラーです(実行結果)。

* What went wrong:
Script compilation error:

  Line 12:     implementation project(":lib")
               ^ Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
                   public val NamedDomainObjectContainer<Configuration>.implementation: NamedDomainObjectProvider<Configuration> defined in org.gradle.kotlin.dsl

→ Kotlin DSLでは関数呼び出しに括弧が必要です。 implementation(project(":lib")) と書き直すと通ります。シングルクォート '...' も、Kotlin DSLでは文字列として使えないので "..." にします。

4. 実行結果が「?????」と文字化けする

今回の検証でも、最初の gradle run では日本語が ?????: 2 / 4 と表示されました。実行環境のロケールがUTF-8でないと、Javaの標準出力の文字コードもUTF-8以外になります。

tasks.named<JavaExec>("run") {
    jvmArgs("-Dstdout.encoding=UTF-8")
}

→ 上のように stdout.encoding を指定すると 完了タスク: 2 / 4 と正しく表示されました。 ソースのコンパイル時の文字化けには tasks.withType<JavaCompile> { options.encoding = "UTF-8" } を使います。

そのほかのよくあるエラー

エラー文(要旨) 原因 対処
Could not find method compile() 削除済みの設定名 implementation などに置き換える
Plugin [id: '...'] was not found プラグインIDや版の誤り、取得先なし IDと版を確認、pluginManagement { repositories { gradlePluginPortal() } }
Unsupported class file major version 69 など Gradle本体が対応していないJavaで動かしている Gradleを上げるか、JAVA_HOME を対応版に
Could not determine the dependencies of task 存在しないモジュールを参照 settings.gradle(.kts) の include を確認
Execution failed for task ':test' / No tests found useJUnitPlatform() 忘れ tasks.named<Test>("test") { useJUnitPlatform() }
Configuration cache problems found ビルドスクリプトが実行時に project を参照 設定時に値を変数へ取り出す(上の hello タスクの val msg = greeting の形)

よくある質問

Q. build.gradleとbuild.gradle.kts、どちらを使えばよいですか? A. 新しく作るならKotlin DSL(build.gradle.kts)がおすすめです。補完と型チェックが効き、gradle init の既定でもあります。既存のGroovy DSLも引き続き使えるので、無理に書き換える必要はありません。モジュールごとに混在させることもできます。

Q. implementationとapiの違いは何ですか? A. どちらも依存を追加しますが、api は「利用側のコンパイル時にもその依存が見える」点が違います。ライブラリの公開メソッドの型に出てくる依存だけ api にし、それ以外は implementation にするとビルドが速くなります。

Q. gradleとgradlewのどちらで実行すればよいですか? A. プロジェクトに gradlew があれば ./gradlew を使います。プロジェクトが決めた版で動くので、人によって結果が変わりません。gradle コマンドは、Wrapperを最初に作るときに使います。

Q. Gradle 9に上げると何が変わりますか? A. Gradle本体の実行にJava 17以上が必要になり、Kotlin DSLのKotlinが2.2系、Groovy DSLのGroovyが4.0系になります。Configuration Cacheが推奨の実行モードになりました。8系の最新で --warning-mode all の警告をなくしてから上げると移行しやすくなります。

まとめ

  • build.gradleは、プラグイン・リポジトリ・依存・タスクを書く設定ファイル。GroovyとKotlinの2つの書き方がある
  • 新規作成はKotlin DSL(build.gradle.kts)。括弧とダブルクォートが必要な点が一番の違い
  • 依存はまず implementation。公開APIの型だけ api、実行時だけなら runtimeOnly、コード生成は annotationProcessor
  • マルチモジュールは settings の include と project(":lib") で、実行順はGradleが自動で決める
  • Wrapperとバージョンカタログで、Gradleとライブラリの版をチーム全員でそろえられる
  • 最新版はGradle 9.8.0。9系はJava 17以上で動き、Configuration Cacheが推奨モード

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「build.gradle書き方|Groovy/Kotlin DSL対訳と依存設定一覧」

株式会社RJCでは、Gradleをはじめとするビルドツールの使い方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?