1. 概要

Gradle は、Javaベースのプロジェクトをビルドするために特別に設計されたGroovyベースのビルド管理システムです。

インストール手順はここにあります。

2. ビルディングブロック–プロジェクトとタスク

Gradleでは、ビルドは1つ以上のプロジェクトで構成され、各プロジェクトは1つ以上のタスクで構成されます。

A project in Gradle can be assembling a jar, war, or even a zip file.

タスクは単一の作業です。これには、クラスのコンパイル、またはJava/Webアーカイブの作成と公開が含まれます。

単純なタスクは次のように定義できます。

task hello {
    doLast {
        println 'Baeldung'
    }
}

If we execute the above task using gradle -q hello command from the same location where build.gradle resides, we should see the output in the console.

2.1. タスク

GradleのビルドスクリプトはGroovyに他なりません。

task toLower {
    doLast {
        String someString = 'HELLO FROM BAELDUNG'
        println "Original: "+ someString
        println "Lower case: " + someString.toLowerCase()
    }
}

他のタスクに依存するタスクを定義できます。 タスクの依存関係は、タスク定義でdependentsOn:taskName引数を渡すことで定義できます。

task helloGradle {
    doLast {
        println 'Hello Gradle!'
    }
}

task fromBaeldung(dependsOn: helloGradle) {
    doLast {
        println "I'm from Baeldung"
    }
}

2.2. タスクに動作を追加する

タスクを定義し、いくつかの追加の動作でそれを強化できます。

task helloBaeldung {
    doLast {
        println 'I will be executed second'
    }
}

helloBaeldung.doFirst {
    println 'I will be executed first'
}

helloBaeldung.doLast {
    println 'I will be executed third'
}

helloBaeldung {
    doLast {
        println 'I will be executed fourth'
    }
}

doFirstdoLastは、それぞれアクションリストの上部と下部にアクションを追加し、は1つのタスクで複数回定義できます。

2.3. タスクプロパティの追加

プロパティを定義することもできます。

task ourTask {
    ext.theProperty = "theValue"
}

ここでは、“ theValue”ourTaskタスクのthePropertyとして設定しています。

3. プラグインの管理

Gradleには、スクリプト、バイナリの2種類のプラグインがあります。

To benefit from additional functionality, every plugin needs to go through two phases: resolving and applying.

解決は、プラグインjarの正しいバージョンを見つけて、それをプロジェクトのクラスパスに追加することを意味します。

プラグインの適用は、プロジェクト Plugin.apply(T)を実行しています。

3.1. スクリプトプラグインの適用

aplugin.gradleでは、タスクを定義できます。

task fromPlugin {
    doLast {
        println "I'm from plugin"
    }
}

このプラグインをプロジェクトbuild.gradleファイルに適用する場合は、次の行をbuild.gradleに追加するだけです。

apply from: 'aplugin.gradle'

これで、 gradle tasks コマンドを実行すると、タスクリストにfromPluginタスクが表示されます。

3.2. プラグインDSLを使用したバイナリプラグインの適用

コアバイナリプラグインを追加する場合は、短い名前またはプラグインIDを追加できます。

plugins {
    id 'application'
}

これで、アプリケーションプラグインの run タスクがプロジェクトで使用可能になり、 runnablejarを実行できるようになります。 コミュニティプラグインを適用するには、完全に修飾されたプラグインIDについて言及する必要があります。

plugins {
    id "org.shipkit.bintray" version "2.3.5"
}

これで、Shipkitタスクがgradleタスクリストで利用できるようになります。

プラグインDSLの制限は次のとおりです。

  • プラグインブロック内のGroovyコードをサポートしていません
  • プラグインブロックは、プロジェクトのビルドスクリプトの最上位ステートメントである必要があります( buildscripts {} ブロックのみがその前に許可されます)
  • プラグインDSLは、スクリプトプラグイン、 settings.gradle ファイル、またはinitスクリプトで記述できません。

プラグインDSLはまだインキュベーション中です。 DSLおよびその他の構成は、Gradle以降のバージョンで変更される可能性があります。

3.3. プラグインを適用するためのレガシー手順

「プラグインの適用」を使用してプラグインを適用することもできます。

apply plugin: 'war'

If we need to add a community plugin, we must add the external jar to the build classpath using the buildscript{} block.

次に、ビルドスクリプトにプラグインを適用できますが、既存のプラグインの後にのみ{}ブロック

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "org.shipkit:shipkit:2.3.5"
    }
}
apply plugin: "org.shipkit.bintray-release"

4. 依存関係の管理

Gradle supports a very flexible dependency management system, it’s compatible with the wide variety of available approaches.

Best practices for dependency management in Gradle are versioning, dynamic versioning, resolving version conflicts, and managing transitive dependencies.

4.1. 依存関係の構成

依存関係はさまざまな構成にグループ化されます。 構成には名前があり、相互に拡張できます

If we apply the Java plugin, we’ll have implementation, testImplementation, runtimeOnly configurations available for grouping our dependencies. The default configuration extends “runtimeOnly”.

4.2. 依存関係の宣言

いくつかの異なる方法を使用して、いくつかの依存関係(SpringとHibernate)を追加する例を見てみましょう。

dependencies {
    implementation group: 
      'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'
    implementation 'org.springframework:spring-core:4.3.5.RELEASE',
            'org.springframework:spring-aop:4.3.5.RELEASE'
    implementation(
        [group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'],
        [group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE']
    )
    testImplementation('org.hibernate:hibernate-core:5.2.12.Final') {
        transitive = true
    }
    runtimeOnly(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') {
        transitive = false
    }
}

We’re declaring dependencies in various configurations: implementation, testImplementation, and runtimeOnly in various formats.

複数のアーティファクトを持つ依存関係が必要になる場合があります。 このような場合、アーティファクトのみの表記 @extensionName (または拡張形式の ext )を追加して、目的のアーティファクトをダウンロードできます。

runtimeOnly "org.codehaus.groovy:groovy-all:2.4.11@jar"
runtimeOnly group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar'

ここでは、 @jar 表記を追加して、依存関係のないjarアーティファクトのみをダウンロードします。

ローカルファイルに依存関係を追加するには、次のようなものを使用できます。

implementation files('libs/joda-time-2.2.jar', 'libs/junit-4.12.jar')
implementation fileTree(dir: 'libs', include: '*.jar')

When we want to avoid transitive dependencies, we can do it on the configuration level or on the dependency level:

configurations {
    testImplementation.exclude module: 'junit'
}
 
testImplementation("org.springframework.batch:spring-batch-test:3.0.7.RELEASE"){
    exclude module: 'junit'
}

5. マルチプロジェクトビルド

5.1. ライフサイクルを構築する

初期化フェーズでは、Gradleはどのプロジェクトがマルチプロジェクトビルドに参加するかを決定します。

これは通常、プロジェクトルートにあるsettings.gradleファイルに記載されています。 Gradleは、参加しているプロジェクトのインスタンスも作成します。

In the configuration phase, all created project instances are configured based on Gradle feature configuration on demand.

In this feature, only required projects are configured for specific task execution. このようにして、大規模なマルチプロジェクトビルドの構成時間が大幅に短縮されます。 この機能はまだインキュベート中です。

ついに、 実行フェーズでは、作成および構成されたタスクのサブセットが実行されます。 コードを含めることができます settings.gradle build.gradle これらの3つのフェーズを認識するためのファイル。

settings.gradle

println 'At initialization phase.'

build.gradle の場合:

println 'At configuration phase.'

task configured { println 'Also at the configuration phase.' }

task execFirstTest { doLast { println 'During the execution phase.' } }

task execSecondTest {
    doFirst { println 'At first during the execution phase.' }
    doLast { println 'At last during the execution phase.' }
    println 'At configuration phase.'
}

5.2. マルチプロジェクトビルドの作成

ルートフォルダーでgradleinit コマンドを実行して、settings.gradleファイルとbuild.gradleファイルの両方のスケルトンを作成できます。

すべての一般的な構成は、ルートビルドスクリプトに保持されます。

allprojects {
    repositories {
        mavenCentral() 
    }
}

subprojects {
    version = '1.0'
}

The setting file needs to include the root project name and subproject name:

rootProject.name = 'multi-project-builds'
include 'greeting-library','greeter'

ここで、マルチプロジェクトビルドのデモを行うには、greeting-libraryおよびgreeterという名前のサブプロジェクトフォルダーがいくつか必要です。 Each subproject needs to have an individual build script to configure its individual dependencies and other necessary configurations.

greeterプロジェクトをgreeting-libraryに依存させたい場合は、greeterのビルドスクリプトに依存関係を含める必要があります。

dependencies {
    implementation project(':greeting-library') 
}

6. Gradleラッパーの使用

GradleプロジェクトにLinux用のgradlewファイルとWindows用のgradlew.batファイルがある場合、プロジェクトをビルドするためにGradleをインストールする必要はありません。

Windowsではgradlew build 、Linuxでは ./ gradlew build を実行すると、gradlewファイルで指定されたGradleディストリビューションが自動的にダウンロードされます。

プロジェクトにGradleラッパーを追加する場合:

gradle wrapper --gradle-version 7.2

コマンドは、プロジェクトのルートから実行する必要があります。 これにより、Gradleラッパーをプロジェクトに結び付けるために必要なすべてのファイルとフォルダーが作成されます。 同じことを行うもう1つの方法は、ラッパータスクをビルドスクリプトに追加することです。

wrapper {
    gradleVersion = '7.2'
}

次に、ラッパータスクを実行する必要があります。タスクにより、プロジェクトがラッパーに関連付けられます。 gradlew ファイルに加えて、ラッパーフォルダーがjarとプロパティファイルを含むgradleフォルダー内に生成されます。

新しいバージョンのGradleに切り替える場合は、 gradle- wrapper.propertiesのエントリを変更するだけで済みます。

7. 結論

この記事では、Gradleを見て、バージョンの競合を解決し、推移的な依存関係を管理するという点で、他の既存のビルドツールよりも柔軟性が高いことを確認しました。

この記事のソースコードは、GitHubから入手できます。