Gradleって何?という方のためにGradleの概要、インストールと設定、代表的なコマンド、チュートリアルで構成しています。
Gradleとは
オープンソースのJavaアプリケーション用ビルドツール.Mavenは設定ファイルをXMLで記述するのに対し,GradleはGroovyで記述できる.そのため柔軟性と可読性が高い.
Groovyのインストール
Gradleの利用だけならGroovyは不要.GradleにはGroovyも含まれている.但し,Groovy自体で開発も出来る環境を作るためGroovyも入れておく.
Macの場合はbrewでインストール出来る
brew install groovy
% exec $SHELL -l
% groovy -v
Groovy Version: 4.0.7 JVM: 18.0.1.1 Vendor: Oracle Corporation OS: Mac OS X
Gradleのインストール
Macの場合はBrewでインストール出来る.
brew install gradle
バージョンの確認
% gradle -v
Welcome to Gradle 7.6!
Here are the highlights of this release:
- Added support for Java 19.
- Introduced `--rerun` flag for individual task rerun.
- Improved dependency block for test suites to be strongly typed.
- Added a pluggable system for Java toolchains provisioning.
For more details see https://docs.gradle.org/7.6/release-notes.html
------------------------------------------------------------
Gradle 7.6
------------------------------------------------------------
Build time: 2022-11-25 13:35:10 UTC
Revision: daece9dbc5b79370cc8e4fd6fe4b2cd400e150a8
Kotlin: 1.7.10
Groovy: 3.0.13
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 18.0.1.1 (Oracle Corporation 18.0.1.1+2-6)
OS: Mac OS X 13.1 aarch64
ターミナルからのプロジェクトの作成
% mkdir gradle-app
% cd gradle-app
% gradle init --type java-library
以下のように対話形式でプロジェクトの設定を入力します.
Starting a Gradle Daemon (subsequent builds will be faster)
Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] no
Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4
Project name (default: gradle-app): gradle-app
Source package (default: gradle.app): gradle.app
> Task :init
Get more help with your project: https://docs.gradle.org/7.6/samples/sample_building_java_libraries.html
BUILD SUCCESSFUL in 1m 56s
2 actionable tasks: 2 executed
gradle initコマンド
- gradleでは
gradle タスク名
の形式で実行します. - ここでは タスク名として
init
を指定して実行しました. init
はプロジェクトの基本的なファイルやフォルダを生成します.--type
は生成するプロジェクトのタイプを指定します.- ここでは
java-library
を指定しました.これはjavaのプロジェクトを指します. - 他にもGroovyやScalaのプロジェクトファイルもサポートされています.
--type
を省略した場合,Gradleプロジェクトの基本的なファイルだけが生成されます.
Gradleタスク
- Gardleの処理はタスクを使って実行します.
- タスクは実行する処理をまとめた単位です.
- タスクにはGradleがデフォルトで用意しているものと,自分で作成できるものがあります.
- プロジェクトのコンパイルや実行もタスクで実行します.
フォルダ構成
% tree -a
.
└── gradle-app
├── .gitattributes
├── .gitignore
├── .gradle
│·· └── file-system.probe
├── gradle
│·· └── wrapper
│·· ├── gradle-wrapper.jar
│·· └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lib
│·· ├── build.gradle
│·· └── src
│·· ├── main
│·· │·· ├── java
│·· │·· │·· └── gradle
│·· │·· │·· └── app
│·· │·· │·· └── Library.java
│·· │·· └── resources
│·· └── test
│·· ├── java
│·· │·· └── gradle
│·· │·· └── app
│·· │·· └── LibraryTest.java
│·· └── resources
└── settings.gradle
フォルダ名 | 説明 |
---|---|
.gradle | タスクで生成されたファイルの保存先 |
src | ソースコード |
build.gradle | Gradleのビルドファイル.プロジェクトのビルド設定を記述する. |
gradlew, gradlew.bat | Gradleのコマンドファイル |
settings.gradle | Gradleの設定情報を記述する |
gradle | 要確認 |
src フォルダ
- src配下にはmainとtestが作成されている.
- mainはアプリケーションのコードの配置場所
- testはユニットテストのコードの配置場所
- src配下の構成は
src/main or test/java/パッケージ名
でMavenと同じ init
時に--type jaav-library
オプションをつけたので,src配下にJava用のサンプルコードが自動生成されている.
ビルド関連ファイル
- build.gradle
- ビルドの内容を記述します.Groovyを使って実行する処理を記述します.
- settings.gradle
- ビルド時の設定情報を記述します.ビルドを実行する前に読み込まれます.必要なライブラリの読み込みなどを記述します.
build.gradleの中身をチェック
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java library project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/7.6/userguide/building_java_projects.html
*/
plugins {
// Apply the java-library plugin for API and implementation separation.
id 'java-library'
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:31.1-jre'
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
- plugins
- 適用するプラグインを記述します.
- repositories
- 参照するリポジトリを記述します.
- mavenCentral()はセントラルリポジトリの情報を返します.
- dependencies
- 依存するライブラリを記述します.
- ライブラリを参照するタイミングとライブラリ (groupId:artifactId)名のペアで記述します.
- tasks
- タスク名と実際に実行するタスクを記述します.
ソースファイルの中身をチェックする
src配下に作成されるコードはいずれもダミーコードの位置づけです.中身はほとんどありません.Library.javaはmainメソッドも実装されていないため,このままでは実行できません.
Library.java
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package gradle.app;
public class Library {
public boolean someLibraryMethod(
) {
return true;
}
}
LibraryTest.java
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package gradle.app;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class LibraryTest {
@Test void someLibraryMethodReturnsTrue() {
Library classUnderTest = new Library();
assertTrue(classUnderTest.someLibraryMethod(), "someLibraryMethod should return 'true'");
}
}
Intellijj IDEAでGradleプロジェクトを作成する
プロジェクトの作成
画面のように入力して新規作成します.
Gradle7.4ではJDK7からJDK16までしかサポートしていないとの警告が表示されます.
JDK選択のダイアログを開きます.
Add JDKを選択します.
Version 17で利用可能なAmazon Correttoを選択します.OracleのJDKを入れたければ事前にOracleのサイトからインストーラーをダウンロードしてインストールしておけば良いと思います.
改めてCreateボタンを押します.
プロジェクトが作成されました.
ビルド関連ファイル
build.gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
settings.gradle
rootProject.name = 'gradle-sample-intellij'
Run Configurationの追加
右上のAdd Configuration
ボタンをクリックします.
Gradleを選択します.
Run/Debug Configuration画面が開きます.
Runからbuild
を選択します.
Nameには自由に名前をつけます.最後にOKを押して完了します.
build taskを実行
先程作成したRun/Debug Configurationが選択されている状態で三角ボタンを押して実行します.
以下のようにログが出力されます.
20:22:08: Executing 'build'...
Starting Gradle Daemon...
Gradle Daemon started in 718 ms
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes
> Task :jar
> Task :assemble
> Task :compileTestJava NO-SOURCE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test NO-SOURCE
> Task :check UP-TO-DATE
> Task :build
BUILD SUCCESSFUL in 2s
2 actionable tasks: 2 executed
20:22:11: Execution finished 'build'.
ビルドが成功しました.
gradle-guiは4.7では利用不可
以前のGradleのバージョンではgradle --gui
でグラフィカルユーザーインターフェースによる設定画面が使えたようですが,ver4.7では利用不可になっているようです.
% gradle --gui
Unknown command-line option '--gui'.
build.gradleの基本を理解する
Gradleのbuild.gradleはGroovyのDSLで記述する
- Gradleはbuild.gradleに書かれているコードを実行することでビルドの処理を行う仕組み.
- build.gradleの書き方が重要
- Gradleのbuild.gradleはGroovyそのもので記述はしない
- GradleはGroovyベースのDSLで記述する
DSLは特定用途言語
- DSLは日本語ではドメイン固有言語と略される
- 特定の用途に限定された言語.
- ベースになる言語を特定用途に限定してアレンジしたもの
- 従って,Gradleで使われている言語は
Groovyをベースにして作成されたGradle DSL
で記述するといのが正しい理解
Gradleのタスクを理解する
- タスクは実行したい処理をひとまとめにしてコマンドとして実行出来るようにしたもの
task タスク名 {
実行する処理
}
タスクはターミナルからgradle タスク名
で実行出来ます.
タスクを実行する
タスクの簡単なサンプルを作成します.build.gradleに以下を追加します.追加するのはターミナルから作成したプロジェクトまたはIntellij IDEAから作成したプロジェクトのどちらでも構いません.
task greeting {
doLast {
println();
println("Hello, World!");
}
}
プロジェクト直下で実行します.以下のように表示されれば成功です.
% gradle greeting
> Task :greeting
Hello, World!
BUILD SUCCESSFUL in 496ms
1 actionable task: 1 executed
taskにはこのようにビルドやコンパイルだけではなく,単にメッセージを出力するだけのようなものも作成できます.
以下のように-q
オプションをつけるとquiet modeで実行できます.quiet modeでは例外発生などの重要な問題以外の表示が抑制されます.
gradle -q greeting
タスクはアクションの組み合わせ
- doLast{ }で記述した内容は予め用意されているdoLast{ }メソッドの内容を上書きする.
- doLastはタスクのアクションリストの最後に処理を追加する.
- アクションリストはアクション(実行する処理)を管理するリスト.
- タスクは内部にさまざまなアクションを所有している.
- タスクを実行すると,用意されたアクションが順番に実行される.
- このアクションを管理しているのがアクションリスト.
- タスクはアクションの組み合わせ.
- doFirstは最初に実行されるアクション.
- doLastは最後に実行されるアクション.
doLastとdoFirstの動きを確認してみます.build.gradleに以下を追加します.
task actionOrder {
doLast {
println("This is last action.");
}
doFirst {
println("This is first action.");
}
}
実行してみます.
% gradle actionOrder -q
This is first action.
This is last action.
記述した順番に関わらず,doFirst, doLastの順番に実行されました.
taskにパラメータを渡す
タスクにはパラメータを渡すことが出来ます.
task count {
doLast {
def total = 0;
for (def i in 1..num.toInteger()) {
total += i
}
printf("total: %s%n", total);
}
}
以下のように -P変数名=xxx
で値を渡せます.
% gradle -q count -Pnum=100
total: 5050
コマンドライン引数はString型で渡されるため,StringからIntegerにパースしています.
動的タスクを生成する
スクリプトで動的にタスクを生成することも出来ます.
def items = ["apple", "orange", "banana"];
items.each {item ->
task "$item" {
doLast {
println("This is task for $item.");
}
}
}
実行します.
% gradle apple -q
This is task for apple.
環境ごとに処理を変えるのに使えそうです.
Java プラグインを使う
Javaの開発で必要となる基本機能はJavaプラグインで提供されています.build.gradleに以下を追加することで利用可能です.
build.configに以下を追加します.
plugins {
id 'java'
}
以下の書き方は現在はレガシーで推奨されていません.
apply plugin: 'java'
apply pluginはレガシーです。
https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_applicationapply pluginなんとなく使わないGradle | ログラス Productチーム アドベントカレンダー 2022プラグインの利用はplugin DSLを利用します。
実行します.
% gradle java
BUILD SUCCESSFUL in 459ms
2 actionable tasks: 2 up-to-date
これでプロジェクトがコンパイルされ,jarファイルが生成されました.クラスファイルはbuild/classesフォルダ内に生成されます.build/libsフォルダ内にjarファイルが生成されます.
gradle java
はクラスファイルを生成し,それらをまとめてjarファイルを生成するという一連の処理を行うタスクです.
gradle buildとgradle javaの違い
- gardle build
- Java,Groovy,ScalaなどGradleがサポートしている.
- gradle buildはサポートしている任意の言語のプロジェクトのビルドを行う.
- gradle java
- Javaプロジェクトのビルドを行う.
- gradle groovy
- Groovyプロジェクトのビルドを行う.
JavaやGroovyプラグインはその言語専用のタスクが用意されている
Javaプラグインのタスク
タスク | 説明 |
---|---|
compileJava | ソースをコンパイルしてbuild/classesに格納する. |
processResources | リソースファイルをbuild/resourcesにコピーする. |
classes | compileJavaとprocessResourcesを一緒にしたもの. |
test | テストの実行.ソースのコンパイル,テストに必要なリソースのコピーなどを実施後,JUnitによるテストを実行. |
compileTestJava, processTestResources, testClasses | それぞれcompileJava, processResources, classesのテスト用.それぞれテストクラスのコンパイル,テスト用リソースのコピー,両者を一緒に実行します. |
jar | コンパイルしてリソースファイルなどを準備した後にjarファイルを作成.Executable Jarを作成するわけではない |
javadoc | ソースを解析しjavadocを生成する.build/docs/javadoc内に生成する. |
clean | ビルドによって生成されたファイルをすべて消去する. |
Javaプラグインのタスクを利用する
build.gradleに以下を追加します.
task createJar(dependsOn: [compileJava, jar]) {
doLast {
println("compiled and jar is created.");
}
}
実行します.
% gradle createJar
> Task :createJar
compiled and jar is created.
BUILD SUCCESSFUL in 580ms
4 actionable tasks: 2 executed, 2 up-to-date
createJar()の引数でdependsOn: [compileJava, jar]
を指定することで,createJarが実行される前に指定した引数のタスクcompileJava
とjar
すべてが実行されます.
そして,最後にdoLastで記述した内容が実行されます.
executeでタスクを直接実行する
以下に記載のあるタスクからタスクを呼び出す方法についてです。
[gradle 3.5] タスクからタスク呼び出し(※executeを使用) – Qiita
非推奨のようです.公式によると,dependenciesを使えるなら使ったほうが良いようです.
The truth is that we don’t officially support calling tasks programmatically. Instead you are supposed to use task dependencies whenever possible. That said, I think task.execute() should work, but as you mentioned it won’t execute dependent tasks.
Gradleでタスクから別のタスクを呼び出す – みちしるべ
tasks
タスクはtasksオブジェクトにまとめられています.
実行可能クラスの用意
src/main/java/org/exampleのMain.javaを以下のように修正.
package org.example;
public class Main {
public static void main(String[] args) {
Main main = new Main();
main.printGreeting("Kenji");
main.printGreeting("Hiroko");
}
public String greeting(String name) {
return String.format("I am %s.", name);
}
public void printGreeting(String name) {
System.out.println(this.greeting(name));
}
}
applicationプラグインを追加
build.gradleに以下を追加
plugins {
id 'java'
id 'application'
}
application {
mainClass = 'org.example.Main'
}
実行します.
% gradle -q run
I am Kenji.
I am Hiroko.
gradle run
は実行前にコンパイルしてくれます.
プログラムを実行するタスクを作成する
runを実行するタスクを作成します.build.gradleに以下を追加します.
task executeMain(dependsOn:[jar, run]) {
doLast {
println("Start execution");
}
}
実行します.
% gradle executeMain
> Task :run
I am Kenji.
I am Hiroko.
> Task :executeMain
Start execution
BUILD SUCCESSFUL in 477ms
5 actionable tasks: 3 executed, 2 up-to-date
Intellij IDEAから実行する
Run/Debug Configurationに以下のように追加します.
このConfigurationが選択されている状態でIntellij IDEAのRunボタンをクリックすればgradle executeMain
が実行されます.
UnitTest
MainTestクラスの作成
package org.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class MainTest {
@Test
public void testMain() {
String name = "Satoshi";
Main main = new Main();
assertNotNull(main);
assertEquals("I am Satoshi.", main.greeting(name));
}
}
実行します.
% gradle test
BUILD SUCCESSFUL in 4s
4 actionable tasks: 4 executed
テストレポート
テスト実行後はテストレポートが作成されます.build/reports/tests/test配下に作成されます.
index.htmlを開きます.以下のようにテストレポートが作成されます.