今回は、Java向けのビルドツールである Gradle を使ってみます。
Java用、もしくは、Javaに使えるビルドツールとして、Make、Ant、Mavenなどがありますが、最近は Gradle がよく使われています。
名前も Gradle(グレードル)が一番かっこいいですし、読み方も明らかでいいですね。Mavenは、メイバンと読むと思ってたんですけど、日本の方はメイブンとかメイベンとか呼んでますね。海外の方のYouTube見ると、メイバンとメイベンの中間ぐらいに聞こえます。
あと、Gradle のロゴも特徴的で良いデザインだと思います!(アイキャッチ画像に使わせてもらいました)
今回は、Gradle を使った簡単なプロジェクトを使って理解していきます。
参考文献
はじめに
「Javaでデザインパターンを学ぶ」の記事一覧です。良かったら参考にしてください。
Javaでデザインパターンの記事一覧
エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
それではやっていきます!
Ubuntu 22.04 に Gradle をインストール
Gradleの公式サイトです。
gradle.org
公式サイトのインストール手順です。最新バージョンは8.7のようです。
Gradle | Installation
公式の手順では、SDKMAN?を使うか、バイナリを手動で入れる方法しかありませんでした。
公式の手順とは違いますが、普通にaptで、Gradleをインストールしてみます。
$ sudo apt install gradle
$ gradle -v
------------------------------------------------------------
Gradle 4.4.1
------------------------------------------------------------
Build time: 2012-12-21 00:00:00 UTC
Revision: none
Groovy: 2.4.21
Ant: Apache Ant(TM) version 1.10.12 compiled on January 17 1970
JVM: 17.0.10 (Private Build 17.0.10+7-Ubuntu-122.04.1)
OS: Linux 6.5.0-28-generic amd64
普通に入れると、かなり古いバージョン(2012年)がインストールされました。
リポジトリを追加してみます。
$ sudo add-apt-repository ppa:cwchien/gradle
$ sudo apt update
$ sudo apt-get upgrade gradle
$ gradle -v
Welcome to Gradle 8.3!
Here are the highlights of this release:
- Faster Java compilation
- Reduced memory usage
- Support for running on Java 20
For more details see https://docs.gradle.org/8.3/release-notes.html
------------------------------------------------------------
Gradle 8.3
------------------------------------------------------------
Build time: 2023-08-17 07:06:47 UTC
Revision: 8afbf24b469158b714b36e84c6f4d4976c86fcd5
Kotlin: 1.9.0
Groovy: 3.0.17
Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM: 17.0.10 (Private Build 17.0.10+7-Ubuntu-122.04.1)
OS: Linux 6.5.0-28-generic amd64
8.3が入りました。とりあえず、これでやっていきます。
公式サイトの Getting Started をやってみる
公式サイトの Getting Started です。
Gradle | Gradle Guides
この中の「Building Java Applications」をやってみます。
プロジェクトのディレクトリを作成
まず、プロジェクトを格納するディレクトリを作ります。demoディレクトリを作ると書かれてましたが、少し変えます。
$ mkdir gradle-demo
$ cd gradle-demo/
初期化タスクを実行する
続いて、init task を実行します。横に値が書いてるのは入力したもので、何も書かれてないのはデフォルトを選択しました。
$ gradle init
Starting a Gradle Daemon (subsequent builds will be faster)
Select type of project to generate:
1: basic
2: application
3: library
4: Gradle plugin
Enter selection (default: basic) [1..4] 2
Select implementation language:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Scala
6: Swift
Enter selection (default: Java) [1..6] 3
Generate multiple subprojects for application? (default: no) [yes, no]
Select build script DSL:
1: Kotlin
2: Groovy
Enter selection (default: Kotlin) [1..2]
Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4]
Project name (default: gradle-demo):
Source package (default: gradle.demo):
Enter target version of Java (min. 7) (default: 17):
Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]
> Task :init
To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.3/samples/sample_building_java_applications.html
BUILD SUCCESSFUL in 1m 51s
2 actionable tasks: 2 executed
途中の「Generate multiple subprojects for application?」がちょっと分からなくて、デフォルトで no でした。
yes にした場合が気になったので、yesにして作ったプロジェクトと比較してみます。
$ colordiff -u gradle-demo gradle-demo-multi/
共通のサブディレクトリー: gradle-demo/.gradle と gradle-demo-multi/.gradle
共通のサブディレクトリー: gradle-demo/app と gradle-demo-multi/app
gradle-demo-multi/ のみに存在: buildSrc
共通のサブディレクトリー: gradle-demo/gradle と gradle-demo-multi/gradle
gradle-demo-multi/ のみに存在: list
diff -u gradle-demo/settings.gradle.kts gradle-demo-multi/settings.gradle.kts
--- gradle-demo/settings.gradle.kts 2024-04-30 00:24:47.943000000 +0900
+++ gradle-demo-multi/settings.gradle.kts 2024-04-30 00:27:22.604000000 +0900
@@ -10,5 +10,5 @@
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
}
-rootProject.name = "gradle-demo"
-include("app")
+rootProject.name = "gradle-demo-multi"
+include("app", "list", "utilities")
gradle-demo-multi/ のみに存在: utilities
multiを選択した場合は、BuildSrcという特別なディレクトリがあって、コードの再利用や、ビルドプロセスのカスタマイズ、プロジェクト構造を整理できるようです(from ChatGPT)。
それでは、multiは選択しない方で、続きをやっていきます。
自動生成されたディレクトリ、ファイルを確認します。
$ tree
.
|-- app
| |-- build.gradle.kts
| `-- src
| |-- main
| | |-- java
| | | `-- gradle
| | | `-- demo
| | | `-- App.java
| | `-- resources
| `-- test
| |-- java
| | `-- gradle
| | `-- demo
| | `-- AppTest.java
| `-- resources
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- settings.gradle.kts
14 directories, 8 files
プロジェクト名を demo
から gradle-demo
に変更したことで、App.java までの階層が1つ深くなりました(プロジェクトをdemoにすると、gradleディレクトリは作られないようです)。
重要なファイルは、以下の3ファイルです。
- settings.gradle.kts:gradle-demoプロジェクトの設定ファイル
- build.gradle.kts:appプロジェクトのビルドスクリプト
- App.java:appプロジェクトのJavaソースファイル
settings.gradle.ktsです。「include("xxx")」を追加すると、「app」と同じようにxxxプロジェクトを追加できます。
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
}
rootProject.name = "gradle-demo"
include("app")
build.gradle.ktsです。分かることは以下です。
- JavaのCLIアプリケーションです
- Maven Centralリポジトリを使っています
- Google製のJavaライブラリ「Guava」を使っています
- Javaはバージョン17が使われています
- エントリポイントは「gradle.demo.App」です
plugins {
application
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("com.google.guava:guava:32.1.1-jre")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
application {
mainClass.set("gradle.demo.App")
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
App.javaです。「Hello World!」を表示するアプリケーションのようです。
package gradle.demo;
public class App {
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}
アプリケーションを実行する
アプリケーションを実行してみます。
$ ./gradlew run
Downloading https://services.gradle.org/distributions/gradle-8.3-bin.zip
............10%............20%.............30%............40%.............50%............60%.............70%............80%.............90%............100%
Path for java installation '/usr/lib/jvm/openjdk-17' (Common Linux Locations) does not contain a java executable
> Task :app:run
Hello World!
BUILD SUCCESSFUL in 48s
2 actionable tasks: 2 executed
アプリケーションが実行されて、「Hello World!」が表示されました。
追加されたディレクトリ、ファイルを確認します。
$ tree
.
|-- app
| |-- build
| | |-- classes
| | | `-- java
| | | `-- main
| | | `-- gradle
| | | `-- demo
| | | `-- App.class
| | |-- generated
| | | `-- sources
| | | |-- annotationProcessor
| | | | `-- java
| | | | `-- main
| | | `-- headers
| | | `-- java
| | | `-- main
| | `-- tmp
| | `-- compileJava
| | `-- previous-compilation-data.bin
| |-- build.gradle.kts
| `-- src
| |-- main
| | |-- java
| | | `-- gradle
| | | `-- demo
| | | `-- App.java
| | `-- resources
| `-- test
| |-- java
| | `-- gradle
| | `-- demo
| | `-- AppTest.java
| `-- resources
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- settings.gradle.kts
30 directories, 10 files
ディレクトリはたくさん増えてますが、ファイルは2つ追加されました。App.class と、previous-compilation-data.bin です。
アプリケーションをビルドする
配布可能なアプリケーションを構築します。
$ ./gradlew build
Path for java installation '/usr/lib/jvm/openjdk-17' (Common Linux Locations) does not contain a java executable
BUILD SUCCESSFUL in 15s
7 actionable tasks: 6 executed, 1 up-to-date
1行目に警告が出ていますが、stack overflowによると、問題ないそうです。
増えたファイルを確認します。
$ tree
.
|-- app
| |-- build
| | |-- classes
| | | `-- java
| | | |-- main
| | | | `-- gradle
| | | | `-- demo
| | | | `-- App.class
| | | `-- test
| | | `-- gradle
| | | `-- demo
| | | `-- AppTest.class
| | |-- distributions
| | | |-- app.tar
| | | `-- app.zip
| | |-- generated
| | | `-- sources
| | | |-- annotationProcessor
| | | | `-- java
| | | | |-- main
| | | | `-- test
| | | `-- headers
| | | `-- java
| | | |-- main
| | | `-- test
| | |-- libs
| | | `-- app.jar
| | |-- reports
| | | `-- tests
| | | `-- test
| | | |-- classes
| | | | `-- gradle.demo.AppTest.html
| | | |-- css
| | | | |-- base-style.css
| | | | `-- style.css
| | | |-- index.html
| | | |-- js
| | | | `-- report.js
| | | `-- packages
| | | `-- gradle.demo.html
| | |-- scripts
| | | |-- app
| | | `-- app.bat
| | |-- test-results
| | | `-- test
| | | |-- TEST-gradle.demo.AppTest.xml
| | | `-- binary
| | | |-- output.bin
| | | |-- output.bin.idx
| | | `-- results.bin
| | `-- tmp
| | |-- compileJava
| | | `-- previous-compilation-data.bin
| | |-- compileTestJava
| | | `-- previous-compilation-data.bin
| | |-- jar
| | | `-- MANIFEST.MF
| | `-- test
| |-- build.gradle.kts
| `-- src
| |-- main
| | |-- java
| | | `-- gradle
| | | `-- demo
| | | `-- App.java
| | `-- resources
| `-- test
| |-- java
| | `-- gradle
| | `-- demo
| | `-- AppTest.java
| `-- resources
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- settings.gradle.kts
51 directories, 28 files
たくさん増えました。重要なのは、app/build/distributions/app.zip(app.tar)でしょうか。
app.zipを解凍して実行してみます。
$ cd app/build/distributions/
$ unzip app.zip
Archive: app.zip
creating: app/
creating: app/lib/
inflating: app/lib/app.jar
inflating: app/lib/guava-32.1.1-jre.jar
inflating: app/lib/failureaccess-1.0.1.jar
inflating: app/lib/jsr305-3.0.2.jar
inflating: app/lib/checker-qual-3.33.0.jar
inflating: app/lib/error_prone_annotations-2.18.0.jar
creating: app/bin/
inflating: app/bin/app
inflating: app/bin/app.bat
$ cd app/bin/
$ ./app
Hello World!
CLI(コマンドラインインタフェース)アプリケーションが作られていて、実行もできました。
アプリケーションをスキャンする
スキャンすると、ビルドの詳細を教えてくれるようです。
$ ./gradlew build --scan
Path for java installation '/usr/lib/jvm/openjdk-17' (Common Linux Locations) does not contain a java executable
BUILD SUCCESSFUL in 1s
7 actionable tasks: 7 up-to-date
Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] yes
Gradle Terms of Service accepted.
Publishing build scan...
https://gradle.com/s/mtyxq5dwgsw76
提示されたURLにアクセスすると、メールアドレスを入力するフォームがあり、入力してGoをクリックすると、メールが届きます(スクショ忘れました)。そのメールのリンクをクリックすると以下のようなビルド結果のレポートページが作成されてました。
全部見れてないですが、豪華で詳細なレポートでした。
おわりに
今回は Gradle を使って、Java のコマンドラインアプリケーションを作ってみました。
次回は、今回作った Gradle プロジェクトを IntelliJ(総合開発環境)でデバッグしたいと思います。
今回は以上です!
最後までお読みいただき、ありがとうございました。