Pengantar Gradle

Artikel ini adalah bagian dari serial: • Pengantar Gradle (artikel saat ini) • Ant vs Maven vs Gradle

• Menulis Plugin Gradle Kustom

• Membuat Fat Jar di Gradle

1. Ikhtisar

Gradle adalah sistem manajemen build berbasis Groovy yang dirancang khusus untuk membangun proyek berbasis Java.

Petunjuk penginstalan dapat ditemukan di sini.

2. Building Block - Proyek dan Tugas

Di Gradle, Build terdiri dari satu atau beberapa proyek dan setiap proyek terdiri dari satu atau beberapa tugas.

Sebuah proyek di Gradle dapat menyusun jar , perang , atau bahkan file zip .

Tugas adalah satu bagian dari pekerjaan. Ini dapat mencakup kompilasi kelas, atau membuat dan menerbitkan arsip Java / web.

Sebuah tugas sederhana dapat didefinisikan sebagai:

task hello { doLast { println 'Baeldung' } }

Jika kita menjalankan tugas di atas menggunakan perintah gradle -q hello dari lokasi yang sama di mana build.gradle berada, kita akan melihat outputnya di konsol.

2.1. Tugas

Skrip build Gradle tidak lain adalah Groovy:

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

Kita dapat mendefinisikan tugas yang bergantung pada tugas lain. Ketergantungan tugas dapat ditentukan dengan meneruskan argumen dependOn: taskName dalam definisi tugas:

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

2.2. Menambahkan Perilaku ke Tugas

Kami dapat menentukan tugas dan meningkatkannya dengan beberapa perilaku tambahan:

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' } }

doFirst dan doLast menambahkan tindakan masing-masing di bagian atas dan bawah daftar tindakan, dan dapat ditentukan beberapa kali dalam satu tugas .

2.3. Menambahkan Properti Tugas

Kami juga dapat mendefinisikan properti:

task ourTask { ext.theProperty = "theValue" } 

Di sini, kita pengaturan sedang “theValue” sebagai theproperty dari ourTask tugas.

3. Mengelola Plugin

Ada dua jenis plugin di Gradle - skrip, dan biner.

Untuk mendapatkan keuntungan dari fungsionalitas tambahan, setiap plugin harus melalui dua tahap: penyelesaian dan penerapan.

Menyelesaikan berarti menemukan versi yang benar dari plugin jar dan menambahkannya ke classpath proyek.

Menerapkan plugin menjalankan Plugin.apply (T) pada proyek .

3.1. Menerapkan Plugin Skrip

Di aplugin.gradle, kita dapat mendefinisikan sebuah tugas:

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

Jika kita ingin menerapkan plugin ini ke file build.gradle proyek kita, yang perlu kita lakukan hanyalah menambahkan baris ini ke build.gradle kita :

apply from: 'aplugin.gradle' 

Sekarang, menjalankan perintah tugas gradle harus menampilkan tugas fromPlugin dalam daftar tugas.

3.2. Menerapkan Plugin Biner Menggunakan Plugin DSL

Dalam kasus menambahkan plugin biner inti, kita dapat menambahkan nama pendek atau id plugin:

plugins { id 'application' }

Sekarang tugas yang dijalankan dari plugin aplikasi harus tersedia dalam proyek untuk menjalankan jar yang dapat dijalankan . Untuk menerapkan plugin komunitas, kami harus menyebutkan ID plugin yang memenuhi syarat:

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

Sekarang, tugas Shipkit harus tersedia di daftar tugas gradle .

Batasan dari DSL plugin adalah:

  • Itu tidak mendukung kode Groovy di dalam blok plugin
  • blok plugin harus menjadi pernyataan tingkat atas dalam skrip build proyek (hanya blok {} build yang diizinkan sebelum itu)
  • Plugin DSL tidak dapat ditulis dalam plugin skrip, file settings.gradle atau dalam skrip init

Plugin DSL masih dalam proses inkubasi. DSL dan konfigurasi lainnya dapat berubah dalam versi Gradle yang lebih baru.

3.3. Prosedur Warisan untuk Menerapkan Plugin

Kami juga dapat menerapkan plugin menggunakan "terapkan plugin" :

apply plugin: 'war'

Jika kita perlu menambahkan plugin komunitas, kita harus menambahkan jar eksternal ke build classpath menggunakan blok {} buildscript .

Then, we can apply the plugin in the build scripts butonly after any existing plugins{} block:

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

4. Dependency Management

Gradle supports 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. Dependency Configuration

Dependencies are grouped into different configurations. A configuration has a name and they can extend each other.

If we apply the Java plugin, we'll have compile, testCompile, runtime configurations available for grouping our dependencies. The default configuration extends “runtime”.

4.2. Declaring Dependencies

Let's look at an example of adding some dependencies (Spring and Hibernate) using several different ways:

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

We're declaring dependencies in various configurations: compile, testCompile, and runtime in various formats.

Sometimes we need dependencies that have multiple artifacts. In such cases, we can add an artifact-only notations @extensionName (or ext in the expanded form) to download the desired artifact:

runtime "org.codehaus.groovy:groovy-all:[email protected]" runtime group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar'

Here, we added the @jar notation to download only the jar artifact without the dependencies.

To add dependencies to any local files, we can use something like this:

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

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

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

5. Multi-Project Builds

5.1. Build Lifecycle

In the initialization phase, Gradle determines which projects are going to take part in a multi-project build.

This is usually mentioned in settings.gradle file, which is located in the project root. Gradle also creates instances of the participating projects.

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

In this feature, only required projects are configured for a specific task execution. This way, configuration time is highly reduced for a large multi-project build. This feature is still incubating.

Finally, in the execution phase, a subset of tasks, created and configured are executed. We can include code in the settings.gradle and build.gradle files to perceive these three phases.

In settings.gradle :

println 'At initialization phase.'

In 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. Creating Multi-Project Build

We can execute the gradle init command in the root folder to create a skeleton for both settings.gradle and build.gradle file.

All common configuration will be kept in the root build script:

allprojects { repositories { mavenCentral() } } subprojects { version = '1.0' }

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

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

Now we need to have a couple of subproject folders named greeting-library and greeter to have a demo of a multi-project build. Each subproject needs to have an individual build script to configure their individual dependencies and other necessary configurations.

If we'd like to have our greeter project dependent on the greeting-library, we need to include the dependency in the build script of greeter:

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

6. Using Gradle Wrapper

If a Gradle project has gradlew file for Linux and gradlew.bat file for Windows, we don't need to install Gradle to build the project.

If we execute gradlew build in Windows and ./gradlew build in Linux, a Gradle distribution specified in gradlew file will be downloaded automatically.

If we'd like to add the Gradle wrapper to our project:

gradle wrapper --gradle-version 4.2.1

The command needs to be executed from the root of the project. This will create all necessary files and folders to tie Gradle wrapper to the project. The other way to do the same is to add the wrapper task to the build script:

task wrapper(type: Wrapper) { gradleVersion = '4.2.1' }

Sekarang kita perlu menjalankan tugas pembungkus dan tugas akan mengikat proyek kita ke pembungkus. Selain file gradlew , folder pembungkus dibuat di dalam folder gradle yang berisi jar dan file properti.

Jika kita ingin beralih ke versi baru Gradle, kita hanya perlu mengubah entri di gradle- wrapper.properties .

7. Kesimpulan

Dalam artikel ini, kita telah melihat Gradle dan melihat bahwa Gradle memiliki fleksibilitas yang lebih besar dibandingkan fitur build lain yang sudah ada dalam hal menyelesaikan konflik versi dan mengelola dependensi transitif.

Kode sumber untuk artikel ini tersedia di GitHub.

Berikutnya » Ant vs Maven vs Gradle