🐘

Gradle Tasks の基本を Spring Boot で学ぶ

2025/02/09に公開

はじめに

前回からの2回目です。
これまでの学習は以下です。

  1. Gradle Projects の基本を Spring Boot で学ぶ

本稿は Tasks が対象です。

Tasks の基本的な 使い方と作り方を、ビルトインタスクおよびカスタムタスク含めて実践します。

[注]

筆者は Java に精通しているわけでも SpringBoot に精通しているわけでもありません。

現在進行形で学習しており、その内容の理解のためにブログにまとめています。
なお、IDEはVSCodeです。

Tasks とは

クラスのコンパイル、JAR の作成、Javadoc の生成、リポジトリへのアーカイブ公開など、ビルドが実行する独立した作業単位です。

とりあえずどんなものがタスクなのかはプロジェクトを作って確認します。

SpringBootプロジェクトをGradleで開始する

SpringBoot プロジェクトの作成は、前回と同様なので割愛します。

どんなものがタスクなのかは、プロジェクト直下で ./gradlew tasks 実行すると確認できます。

------------------------------------------------------------
Tasks runnable from root project 'demo'
------------------------------------------------------------

Application tasks
-----------------
bootRun - Runs this project as a Spring Boot application.
bootTestRun - Runs this project as a Spring Boot application using the test runtime classpath.

Build tasks
-----------
assemble - Assembles the outputs of this project.
bootBuildImage - Builds an OCI image of the application using the output of the bootJar task
bootJar - Assembles an executable jar archive containing the main classes and their dependencies.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the classes of the 'main' feature.
// 割愛

ここに表示されているものは、 ./gradlew xxx でそれぞれ実行されます。

表示された Task の詳細は help --task <task> で確認できます。

下記の Task は org.springframework.boot の Plugin から実行されているのが分かります。

./gradlew help --task bootRun

> Task :help
Detailed task information for bootRun

Path
     :bootRun

Type
     BootRun (org.springframework.boot.gradle.tasks.run.BootRun)

Options
     --args     Command line arguments passed to the main class.

     --debug-jvm     Enable debugging for the process. The process is started suspended and listening on port 5005.

     --no-debug-jvm     Disables option --debug-jvm.

     --rerun     Causes the task to be re-run even if up-to-date.

Description
     Runs this project as a Spring Boot application.

Group
     application

BUILD SUCCESSFUL in 625ms
1 actionable task: 1 executed

build.gradle を眺め直して、前回スルーした tasks を確認します。

// build.gradle
// 割愛
tasks.named('test') {
	useJUnitPlatform()
}

help --task <task> で確認すると、GradleのAPIを利用して、JUnit Platform を使用するように設定していることが分かります。

> Task :help
Detailed task information for test

Path
     :test

Type
     Test (org.gradle.api.tasks.testing.Test)

Options
     --debug-jvm     Enable debugging for the test process. The process is started suspended and listening on port 5005.

     --no-debug-jvm     Disables option --debug-jvm.

     --fail-fast     Stops test execution after the first failed test.

     --no-fail-fast     Disables option --fail-fast.

     --test-dry-run     Simulate test execution.

     --no-test-dry-run     Disables option --test-dry-run.

     --tests     Sets test class or method name to be included (in addition to the test task filters), '*' is supported.

     --rerun     Causes the task to be re-run even if up-to-date.

Description
     Runs the test suite.

Group
     verification

BUILD SUCCESSFUL in 692ms
1 actionable task: 1 executed

この Task を実行してみます。

./gradlew ${taskName} で実行します。

./gradlew test 

BUILD SUCCESSFUL in 2s
6 actionable tasks: 2 executed, 4 up-to-date

Task の利用方法は把握したので、次は簡単な Task を作成してみます。

基本的なタスクを作成

// build.gradle
tasks.register('hello') {
    description = 'Prints hello world.'
    group = 'Demo'
    doFirst {
        println 'Hello'
    }
    doLast {
        println 'World'
    }
}

下記のように実行します。なお、 doFirst や doLast は TaskAPIメソッドを参照

(マルチプロジェクトの場合、 ./gradlew :${subProjectName}:${taskName} です。)

./gradlew hello           

> Task :hello
Hello
World

依存性をもつタスクを作成

続けて、他の Task に依存する Task を作ります。

tasks.register('hello') {
    description = 'Prints hello world.'
    group = 'Demo'
    doFirst {
        println 'Hello'
    }
    doLast {
        println 'World'
    }
}
tasks.register('intro') {
    dependsOn tasks.hello
    doLast {
        println "I'm Gradle"
    }
}

intro Task は、 hello Task に依存するため、以下のように実行されます。

./gradlew intro      

> Task :hello
Hello
World

> Task :intro
I'm Gradle

ビルトインタスクを使ってみる

Gradle はファイルコピー・削除など、一般的に利用される機能をビルトインタスクとして用意してくれています。
どのような種類があるかは DSL のTask Typesを参考にすると良さそうです。

以下例ではファイルコピーをしてみます。

// source,targetディレクトリをプロジェクト直下に作成
// source/hoge.txt, fuga.txtを作成しているとする
tasks.register('copyTask', Copy) {
    from("source")
    into("target")
    include("*.txt")
}
./gradlew copyTask

BUILD SUCCESSFUL in 805ms
1 actionable task: 1 executed

❯ ls target     
fuga.txt        hoge.txt

最後に、ユーザー独自のカスタムタスクを作ってみます。

カスタムタスクを作ってみる

カスタムタスクは DeafultTask を拡張して作成します。
そして、 @TaskAction ハンドラーを実装する必要があります。
カスタムタスクを ./buildSrc/src/main/groovy に配置します。

Input と Output のアノテーションについては Annotating inputs and outputs を参考にすると良さそうです。

project オブジェクトについては Understanding Propertiesを参考にします。

// demo/buildSrc/src/main/groovy/GreetingTask.groovy
package demo

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.api.provider.Property

abstract class GreetingTask extends DefaultTask {

    @Input
    def greeting = project.objects.property(String)

    @Input
    def client = project.objects.property(String)

    @TaskAction
    void greet() {
        println "${greeting.get()} ${client.get()}!"
    }

}

// build.gradle
tasks.register("greet", demo.GreetingTask) {
    description = "Greets someone"
    group = "Custom"

    greeting.set("Hi")
    client.set("SpringBoot")
}

tasks.build.dependsOn("greet")
./gradlew greet

> Task :greet
Hi SpringBoot!

BUILD SUCCESSFUL in 690ms
3 actionable tasks: 1 executed, 2 up-to-date

以上、簡単な Task を作って、 Tasks の使い方と作り方の基本を理解しました。

次は、Plugins の基本を学びます。

参考リンク

Discussion