プロジェクト

全般

プロフィール

Gradleの使い方

2021-05-06時点のGradle最新バージョンは 7.0 です。

Gradleを使う最初の一歩

Gradleツールのセットアップ

Gradle公式サイトのリリースページ(次のURL)にアクセスし、ダウンロードするバージョンの[binary-only]または[complete]のリンクをクリックします。
https://gradle.org/releases/

  • binary-only
    gradle実行スクリプトファイル、実行に必要なライブラリファイル(JARファイル群)が含まれています。
  • complete
    binary-onlyに、ドキュメントおよびソースファイルが追加されています。

Windows OS環境へのGradleのインストール

インストール先(例、C:\Program Files\Java の下)にダウンロードしたアーカイブファイルを解凍し展開します。
環境変数PATHに、C:\Program Files\Java\gradle-7.0\bin を追加します。
Gradleはシステム(環境変数PATH)上にあるJavaを使用します。また、環境変数JAVA_HOMEを指定してシステム上とは別のJavaを使用することが可能です。

最小限のJavaビルドプロジェクト

まず最初は、もっとも最低限の記述でJavaソースファイルをビルドするGradleのビルドプロジェクトを作成します。
Gradleのinitタスクを実行し、必要な設定や雛形を自動生成します。

プロジェクトディレクトリの作成

開発するプロジェクトのディレクトリを作成します。

D:\work> mkdir HelloApp
D:\work> cd HelloApp
D:\work\HelloApp>

ひとまず空のディレクトリ D:\work\HelloApp を用意しました。

gradleのinitタスクを実行

JDKとGradleにPATHを通した状態で gradle init を実行します。
対話的にいくつかの設定を指示すると、プロジェクトのディレクトリ・ファイルが生成されます。

以下はGradle 7.0で実行したときの例です。

D:\work\HelloApp> gradle init
Welcome to Gradle 7.0!

Here are the highlights of this release:
 - File system watching enabled by default
 - Support for running with and building Java 16 projects
 - Native support for Apple Silicon processors
 - Dependency catalog feature preview

For more details see https://docs.gradle.org/7.0/release-notes.html

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             <--- Java実行可能プロジェクト

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..5] 3              <--- Java

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1            <--- build.gradleの記述はGroovyで

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1   <-- 単一のプロジェクトとする

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1       <-- 今回はGroovyで

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4] 4           <--- JUnit5 を使う

Project name (default: HelloApp):                     <--- ディレクトリ名と同じでよければ[Enter]キー入力                               
Source package (default: HelloApp): com.torutk.hello  <--- 作成するプログラムのパッケージ名を入力

> Task :init
Get more help with your project: https://docs.gradle.org/6.4/userguide/tutorial_java_projects.html

BUILD SUCCESSFUL in 7m 47s
2 actionable tasks: 2 executed
D:\work\HelloApp> 

Gradleのinitタスクを実行すると、対話的にプロジェクトの種類や設定を入力し、それに従ったプロジェクトディレクトリ・ファイルが生成されます。このディレクトリ構造は次となります。

D:\work\HelloApp
│  .gitattributes
│  .gitignore
│  gradlew
│  gradlew.bat
│  settings.gradle
│
├─.gradle
│  ├─7.0
│  │  │  gc.properties
│  │  │
│  │  ├─dependencies-accessors
│  │  │      dependencies-accessors.lock
│  │  │      gc.properties
│  │  │
│  │  ├─executionHistory
│  │  │      executionHistory.bin
│  │  │      executionHistory.lock
│  │  │
│  │  ├─fileChanges
│  │  │      last-build.bin
│  │  │
│  │  ├─fileHashes
│  │  │      fileHashes.bin
│  │  │      fileHashes.lock
│  │  │
│  │  └─vcsMetadata-1
│  ├─buildOutputCleanup
│  │      buildOutputCleanup.lock
│  │      cache.properties
│  │      outputFiles.bin
│  │
│  ├─checksums
│  │      checksums.lock
│  │
│  ├─configuration-cache
│  │      gc.properties
│  │
│  └─vcs-1
│          gc.properties
│
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
└─app
    └─src
        │  build.gradle
        │
        ├─main
        │  ├─java
        │  │  └─com
        │  │      └─torutk
        │  │          └─hello
        │  │                  App.java
        │  │
        │  └─resources
        └─test
            ├─java
            │  └─com
            │      └─torutk
            │          └─hello
            │                  AppTest.java
            │
            └─resources

build.gradle

ビルドの定義はbuild.gradleファイルに記述します。initタスク(プロジェクト種類:application、言語:Java)で生成されたbuild.gradleの内容(コメント行を除く)は次です。

plugins {
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
    implementation 'com.google.guava:guava:30.0-jre'
}

application {
    mainClass = 'com.torutk.hello.App'
}

tasks.named('test') {
    useJUnitPlatform()
}
App.java

initタスクでは、指定したパッケージにmainメソッドを持つ雛形クラスのソースファイルが1つ生成されます。

  • src/main/java/com/torutk/hello/App.java
    package com.torutk.hello;
    
    public class App {
        public String getGreeting() {
            return "Hello world!";
        }
    
        public static void main(String[] args) {
            System.out.println(new App().getGreeting());
        }
    }
    
.gitignore

gitリポジトリに登録しないgradleプロジェクトのディレクトリを設定したgit無視ファイルが生成されます。

  • .gitignore
    .gradle
    build
    
.gitattributes

gitリポジトリに登録する際のファイル属性を設定したgit属性ファイルが生成されます。

  • .gitattributes
    *.bat      text eol=crlf
    

これは、gradlew.bat に対応するものです。

ビルドの実行と生成される成果物ディレクトリ・ファイル

gradlew.bat を実行します。コマンドラインオプションには、ターゲット(ビルドの場合は build)を指定します。

D:\work\HelloApp> gradlew build
Downloading https://services.gradle.org/distributions/gradle-6.4-bin.zip
.........10%..........20%..........30%..........40%.........50%..........60%..........70%..........80%.........90%..........100%

BUILD SUCCESSFUL in 23s
7 actionable tasks: 7 executed

ビルド結果次のディレクトリ・ファイルが生成されます。

C:\work\HelloApp\app
├─build
   ├─classes
   │  └─java
   │      ├─main
   │      │  └─com
   │      │      └─torutk
   │      │          └─hello
   │      │                  App.class
   │      │
   │      └─test
   │          └─com
   │              └─torutk
   │                  └─hello
    │                          AppTest.class
   │
   ├─distributions
   │      app.tar
   │      app.zip
   │
   ├─generated
   │  └─sources
   │      ├─annotationProcessor
   │      │  └─java
   │      │      ├─main
   │      │      └─test
   │      └─headers
   │          └─java
   │              ├─main
   │              └─test
   ├─libs
   │      app.jar
   │
   ├─reports
   │  └─tests
   │      └─test
   │          │  index.html
   │          │
   │          ├─classes
   │          │      com.torutk.hello.AppTest.html
   │          │
   │          ├─css
   │          │      base-style.css
   │          │      style.css
   │          │
   │          ├─js
   │          │      report.js
   │          │
   │          └─packages
   │                  com.torutk.hello.html
   │
   ├─scripts
   │      app
   │      app.bat
   │
   ├─test-results
   │  └─test
   │      │  TEST-com.torutk.hello.AppTest.xml
   │      │
   │      └─binary
   │              output.bin
   │              output.bin.idx
   │              results.bin
   │
   └─tmp
       ├─compileJava
       │  │  source-classes-mapping.txt
       │
       ├─compileTestJava
       │  │  source-classes-mapping.txt
       │  
       ├─jar
       │  │  MANIFEST.MF
       │  
        └─test

プログラムの実行

runタスクでプログラムを実行します。

D:\work\HelloApp> gradlew run

> Task :app:run
Hello world!

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

D:\work\HelloApp>

buildタスクで生成されたjarファイルをjavaコマンドから実行することも可能です。

D:\work\HelloApp> java -jar build\libs\HelloApp.jar
Hello world.
 
D:\work\HelloApp>

プログラムの実行時にコマンドライン引数を渡す

Javaプログラムにコマンドライン引数を渡すには、gradleのrunタスクの後に--argsオプションでコマンドライン引数の全体の文字列を指定します。

D:\work\HelloApp> gradlew run --args="--x=200 --y=300" 
:

ビルド生成物の削除(クリーン)

ビルドによって生成されたディレクトリ・ファイルを削除します。

D:\work\HelloApp> gradlew clean
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

D:\work\HelloApp> 

ユニットテストの実行

testタスクでユニットテストを実行します。実行結果はレポートファイルに出力されます。

D:\work\HelloApp> gradlew test

BUILD SUCCESSFUL in 2s
3 actionable tasks: 3 executed
D:\work\HelloApp> 

テスト結果は次に生成されます。
D:\work\HelloApp\build\reports\tests\test\index.html

ブラウザに表示させたものは次です。

clipboard-202005081413-sfxun.png

次の一歩

ライブラリを使用する

Mavenリポジトリを指定する

Sonatype社 が提供するソフトウェア配布サービス Central Repository で、mavenのデフォルトのリポジトリです。Central Repository 上のライブラリを利用するときは次のように定義します。

repositories {
  mavenCentral()
}

他の定義済みリポジトリ

  • jcenter()
    JFrog社 が提供するソフトウェア配布サービス Bintray を利用するmaven互換リポジトリですが、2022年1月をもって提供をやめるとのアナウンスが出ています。

独自のリポジトリを使用するときは、そのリポジトリのURLを指定します。

repositories {
  maven {
    "http://repo.example.com/maven2" 
  }
}

ローカルマシン上のファイルを指定する

ローカルマシンに配置したライブラリを使用することができます。

flatDir でライブラリを置くディレクトリをリポジトリ指定する方法

リポジトリ指定でflatDirを用いてライブラリを収めたフォルダを指定します。

repositories {
  flatDir {
    dirs 'relative/to/dir', '/absolute/to/dir', "${junit5}" 
  }
}

junit5 プロパティは、gradle.propertiesファイルやコマンドラインから指定します。

  • gradle.properties
    junit5 = C:/Program Files/Java/junit5
    

ピリオドを含むプロパティ名を使用すると、例えば ${junit5.dir} の様に参照するとエラーとなります。ピリオドがメソッド呼び出し式と扱われるためです。この場合は、次のいずれかの指定をして回避します。

dirs getProperty("junit5.dir")
dirs "${property('junit5.dir')}"
dirs "${project.'junit5.dir'}"

fileTreeでライブラリのディレクトリとファイル名を指定する方法

依存関係指定でfileTreeを用いてライブラリファイルのディレクトリと名前を指定します。

dependencies {
    implementation fileTree(dir: "javafx-gadgetsupport/dist", includes: ['*.jar'])
}

ディレクトリ指定は相対パス、絶対パスの指定が可能です。

使用するライブラリを指定する

dependencies {
  implementation 'org.slf4j:slf4j-api:1.7.13'
  testImplementation 'junit:junit:4.12'
}

コンパイル時および実行時の双方に使用するライブラリは、implementationで名称を指定します。
テストのコンパイル時およびテストの実行時に使用する(開発対象プログラムの中では使用しない)ライブラリは、testImplementationで名称を指定します。
その他、compileOnlyruntimeOnlytestCompileOnlytestRuntimeOnlyapiなどの指定があります。

従来使っていたcompileruntimetestCompiletestRuntimeは非推奨となっており、今後のバージョンで使用できなくなります。

Javaのバージョン指定

ソースファイルの記述(言語仕様)バージョン、およびコンパイル後のクラスファイルのバージョンを指定します。

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

文字コードの指定

ソースファイルの文字コードがシステムのエンコーディングと異なる場合は、コンパイルオプションにエンコーディング指定を追加します。
幾つか方法がありますが、以下が柔軟に対応できます。

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

JVMオプション指定

アプリケーション実行時にjavaコマンドのオプションを指定する

application {
    applicationDefaultJvmArgs = ['-Dgreeting.language=en']
}

JPMSのモジュール対応

モジュール対応JAR

Gradle 7.0からこの記述は不要となりました。

java {
    modularity.inferModulePath = true
}

この設定で、モジュール対応JARライブラリ参照をモジュールパスとして扱われます。

メインクラスを持つモジュール対応JAR

application {
    mainModule = 'org.gradle.sample.app' // name defined in module-info.java
    mainClass = 'org.gradle.sample.Main'
}

参考

Java 9 Jigsaw support #890
Building JPMS Modules with Gradle (Youtube)

ソースディレクトリの構成を変更

デフォルトでは、Javaのソースファイルは src/main/java ディレクトリの下に置かれている前提となっています。また、ソースファイル以外のリソースファイルは src/main/resources ディレクトリに置かれる前提となっています。

これを変更する場合、例えばJavaソースファイルおよびリソースファイルをともに src ディレクトリ下に置くには、sourceSets を定義します。

sourceSets {
    main {
        java {
            srcDirs = ['src']
        }
        resources {
            srcDirs = ['src']
        }
    }
}

サンプル等

単一モジュールのGradleプロジェクト

複数モジュールのGradleプロジェクト

ユニットテスト

JUnit 5

  • [#116] GradleでJUnit5テストをローカルマシンで実施する

応用

依存するライブラリをダウンロードする

参照:調査チケット #79

Gradleでは依存するライブラリを、実行した環境のキャッシュディレクトリ(ユーザー固有のディレクトリで、Windows上であれば%USERPROFILE%\.gradle\caches\modules-2\files-2.1\の下、caches以下のディレクトリ名はGradleのバージョンにより変わるかも)に保持します。
ここにはその環境で過去実施したビルドで使用した依存ライブラリが一緒くたに置かれるので、あるライブラリとその依存ライブラリだけを抽出したいときには対応に苦慮します。

そこで、依存するライブラリをダウンロードする専用のビルド定義を記述し必要なものだけダウンロードします。

依存するライブラリのダウンロード定義

apply plugin: 'java'

def libDir = 'lib'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.jvnet.com4j:com4j:2.1'
}

task deleteDeps(type: Delete) {
    delete libDir
}

task copyDeps(type: Copy, dependsOn: deleteDeps) {
    from configurations.testRuntime
    into libDir
}

dependencies には、ビルドするときに定義するライブラリの記述と同様にダウンロードしたいライブラリを記述します。
コピータスク(copyDeps)で、testRuntimeを指定しているのは、依存するライブラリの範囲を最大にしているためです。ここをcompileと指定すればコンパイルに必要なものだけダウンロードします(その場合、実行時に必要なライブラリが抜ける可能性があります)。

Gradleのバージョンを更新する

Gradleプロジェクトでwrapperを使用しているときのgradleバージョン更新

  • 現在のGradleプロジェクトが使用するGradleバージョンを確認
    D:\work\myproj> gradlew -v
    
    ------------------------------------------------------------
    Gradle 6.5.1
    ------------------------------------------------------------
     :
    
  • Gradleプロジェクトのwrapperで使用するgradleバージョンを更新
    最新のリリースバージョンである6.8.3に更新するときの例を次に示します。
    D:\work\myproj> gradlew wrapper --gradle-version=6.8.3
    
    

    このコマンドは、gradle/wrapper/gradle-wrapper.properties ファイルを更新します。
  • Gradleの本体、バッチ・スクリプト更新を更新するには次を実行
    D:\work\myproj> gradlew wrapper
    
    

Gradleの機能

プラグイン

Build Init プラグイン

Gradleビルドプロジェクトの新規作成を行うプラグインです。

  1. ビルド種類(build type)
  2. DSL言語(ビルド定義を記述する言語、GroovyかKotlinか)
  3. ビルド種類がJava系の場合、テストフレームワーク

Java用のビルドでは、次のオプションをコマンドライン指定または対話的に入力します。

オプション名 オプション指定 オプションの値 備考
ビルド種類 --build-type java-application, java-library
DSL言語 --dsl groovy, kotlin
テストフレームワーク --test-framework junit4, junit-jupiter, spock, testng
プロジェクト名 --project-name プロジェクト名 成果物(JARファイル等)の名称に使われる
パッケージ名 --package パッケージ名 成果物の代表パッケージ名

javaプラグイン

Javaのライブラリを作成する際に有用なプラグインです。次のタスクが提供されています。

classes
testClasses
compileJava
compileTestJava
jar
test
javadoc
clean
assemble
check
bulid
buildNeeded
buildDependents
processResources
processTestResources
uploadArchives

新規にプロジェクトを作成するときのテンプレート生成も提供されています。

work$ gradle init --type java-library
:wrapper
:init

BUILD SUCCESSFUL

Total time: 1.62 secs

work$ ls
build.gradle*  gradle/  gradlew*  gradlew.bat*  settings.gradle*  src/

生成されるbuild.gradleは次になります(コメントを削除しています)。

apply plugin: 'java'

repositories {
    jcenter()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.13'
    testCompile 'junit:junit:4.12'
}

javacコンパイルオプション

compilerArgsに任意のオプションを記述するとコンパイル時にjavacコマンドのオプションとして適用されます。
Gradle User Manual - CompileOptions

compileJava {
    options.compilerArgs.addAll(['--release', '7'])
}

Gradleの記述方法

Gradleは、Groovy言語で記述します(その後Kotlin言語で記述することもできるようになりました)。

Groovyの記法メモ

Groovy は、一つの事を記述するのに複数の書き方があり、混沌に属する言語です(まるでPerlの再来)。

  • メソッド呼び出し式では括弧を省略
  • プロパティ風な書き方で、setterメソッドの代わりに代入式を書ける
  • 名前付き引数(これと括弧の省略を合わせると何が何だかな記法になる)
  • 波括弧でクロージャー(コードブロック)

Gradleのバージョン

バージョンの変遷(トピック)

  • v6.4.1 2020-05-15
    Javaモジュールシステムに対応