JavaRush /Java Blog /Random EN /A quick introduction to Gradle
Viacheslav
Level 3

A quick introduction to Gradle

Published in the Random EN group

Introduction

The topic of this review will be the Gradle automatic build system. In English, build systems are called Build Tools . A quick introduction to Gradle - 1Why is this even necessary? Manually building projects in Java is a rather labor-intensive process. It is necessary to correctly indicate the libraries and frameworks that the project needs and on which the project depends. Here you can read an excellent article on Habré: “ Working with Java on the command line .” Sooner or later you will start creating some scripts to automate this process. Now imagine that all developers around the world do this and everyone writes again what someone has already written for their project. And then project assembly systems appeared that automate this process. In addition, on the one hand, they allow you to assemble a project the way you want it, on the other hand, they provide you with more or less standardized tools. An alternative to Gradle is the Maven automated build system. These two assembly systems are, on the one hand, different, but on the other hand, they have a number of similarities. There is material on this topic on the Gradle website: " Migrating from Maven to Gradle ". As stated in this tutorial, Gradle and Maven have a different perspective on how to build a project. Gradle is based on a graph of tasks, which can depend on each other. Tasks do some kind of work. Maven uses a model of certain phases, to which certain “goals” are attached. These goals are where some work is done. However, with these different approaches, both build systems follow the same convention and dependency management is similar. To start using Gradle you need to download it. In Google or Yandex we enter “Gradle Build Tool” and in the first results we see the official website: https://gradle.org . On the main Gradle page there is a link with the text "Docs", which leads to the Gradle documentation . First, we need to install (Install) Gradle, so we are interested in the " Installing Gradle " section of the documentation. There are many installation methods, including the “old fashioned” method, i.e. manually (“ Installing manually ”). According to the instructions, download a file of the “ binary-only ” type, which will have a name like gradle-5.1.1-bin.zip. Next, unpack the archive and configure the PATH environment variable according to the instructions. The main thing is that after executing the instructions, the command gradle -vshows the version of the installed Gradle. There may be a problem that when determining the location, the system will find Gradle not where you want. Therefore, on Windows you can do (on *nix there are analogues): for %i in (gradle.bat) do @echo. %~$PATH:i Now, perhaps, we can start getting acquainted.
A quick introduction to Gradle - 2

Initializing a Gradle project

I would like to immediately note that Gradle is about performing tasks called tasks (I will call them tasks). Tasks are provided by various plugins . I advise you to read more about plugins in the official documentation: " Using Gradle Plugins ". There is a set of "Core Plugins" that are always available when Gradle is installed. There are different categories of these plugins, but we are interested in the " Utility " category. This set includes the " Build Init Plugin " plugin, which provides tasks for initializing a Gradle project. We are interested in creating a project type: " java-application ". Let's run the Gradle task: gradle init --type java-application Let's answer some questions along the way, for example, that we want to use the Groovy DSL (standard task description language for Gradle) and the JUnit testing framework (we'll talk about this in another review). After creation we will receive the following set of files:
A quick introduction to Gradle - 3
Firstly, after initialization we receive a special wrapper pre-configured for our version of Gradle - this is a special script. I advise you to read more about it in the official documentation - " The Gradle Wrapper ". Secondly, we see the Gradle Build Script - the build.gradle file. This is the main file, which describes which libraries and frameworks our project uses, which plugins need to be connected to the project and describes various tasks. I advise you to read more about this file in the official documentation: " Build Script Basics ".
A quick introduction to Gradle - 4

Plugins and Tasks

If we look now at the contents of the Build Script, we will see the plugins section:
plugins {
    id 'java'
    id 'application'
}
These are the same plugins that we talked about earlier. And if there are plugins, then there are tasks that are now available to us. We can run the gradle tasks command and see what we can now do with the project:
A quick introduction to Gradle - 5
For example, by executing gradle runwe will launch the main class of our java application:
A quick introduction to Gradle - 6
As we can see, the same is written below. 2 actionable tasks: 1 executed, 1 up-to-date What does this mean? This means that a total of 2 tasks were completed: Moreover, 1 was actually completed, and one was not executed, because... it is up-to-date, that is, the state is current and nothing has been done. We can execute the so-called "Dry Run": gradle run -m Let's execute this command, we will see what tasks will be executed to execute the run task:
A quick introduction to Gradle - 7
As we can see, a total of 4 tasks were completed: before run was executed, it executed the dependency task classes. The classes itself has 2 dependencies and therefore it also executed compileJava and processResources. When we perform a task, we can perform it while viewing a certain level of logs (the logging level determines how important messages we want to see). For example, we can do gradle run -i. This will also show us informational messages like:
Task :classes UP-TO-DATE
Skipping task ':classes' as it has no actions.
For more information about logging in Gradle, I advise you to refer to the official documentation: " Gradle Logging ". As we can see, the classes task was skipped because it is UP-TO-DATE , that is, the state is current, nothing needs to be done, so there were no actions. This is because by default Gradle has " Up-to-date checks " or the so-called incremental build. You can read more about this mechanism in the Gradle documentation: " Up-to-date checks (AKA Incremental Build) ". But this mechanism can be disabled by executing a task specifying the --rerun-tasks flag. For example, gradle run --rerun-tasks. Then we will see: 2 actionable tasks: 2 executed As you can see, the number of executed tasks takes into account only the first level of the graph, that is, the run task itself and those tasks on which it directly depends, that is, classes. Tasks on which classes depend are not counted here (although they are executed when the classes task is executed). You should also read about the tasks:
A quick introduction to Gradle - 8

Dependencies

One of the main tasks of any build system is managing dependencies, that is, which libraries/frameworks our project needs. The build system must ensure that they are available at the right time and assemble the final artifact of our application in the right way. By default, after gradle init for java-application, we will see the following content in the build script:
dependencies {
    implementation 'com.google.guava:guava:26.0-jre'
    testImplementation 'junit:junit:4.12'
}
Here it is immediately clear what we are connecting. But without some understanding, it is not clear what implementation and testImplementation are? Here we need to turn again to the Gradle documentation, since Gradle’s documentation is well written. It's called " Managing Dependency Configurations ". As stated in the documentation, each dependency is declared with a certain scope - the area within which this dependency will be available. This scope is designated by some configuration, each of which has a unique name. It’s also interesting that many Gradle plugins add predefined configurations. To find out what configurations we have we can run: gradle --console plain dependencies This way we will see a list of all available configurations and their dependencies. We can filter this list so that we see only the available configurations themselves: gradle --console plain dependencies | find " - " How do we know what to use? You'll have to do a little reading here. Because We use the "Java" plugin, so let's start with its documentation and the " Dependency management " section. Here we see that there used to be a configuration (aka scope) called “compile” and it meant “dependency needed during compilation”. But then it was replaced (in English Superseded) with implementation. You can read more about replacement in the section " API and implementation separation ". It turns out that this dependency will be on the “compile classpath”. But sometimes we want our dependency to be included in the final artifact. For what? For example, we will have an executable jar, which should itself contain everything necessary. What then should we do? Firstly, there is no such support “out of the box” (that is, by default, without any additional actions). This is explained by the fact that everyone wants to collect the archive in their own way, and Gradle tries to be minimalistic. We also cannot use jar archives on the classpath (without additional manipulations in the code), because it doesn't work that way (See " Oracle: Adding Classes to the JAR File's Classpath " for more details). Therefore, the most beautiful way is the following code in the build script:
jar {
    manifest {
        attributes 'Main-Class': 'jrgradle.App'
    }
    from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
In the jar task settings we specify what will be added to the jar file manifest (see " Oracle: Setting an Application's Entry Point "). And then we say that all the dependencies that were needed for compilation will be included in the jar. An alternative is to use the " Gradle Shadow Plugin ". It may seem complicated, but other plugins can make life easier. For example, when creating a web application (as opposed to a regular running java application), we will use a special plugin - “ Gradle War Plugin ”, which has a different behavior and our life will be easier there (all the necessary dependencies will be put in a separate special directory by the plugin itself . Such work is regulated by how web applications should be structured. But that's a completely different story).
A quick introduction to Gradle - 9

Results

Gradle is an excellent choice for project build systems. This is confirmed by the fact that it is used by developers of such well-known projects as Spring and Hibernate. Only the most basic things were discussed above. Behind them are hidden a million features and opportunities that developers have. Gradle also supports the creation of multi-module projects, which is not covered in this review, but Gradle itself has an excellent tutorial: “ Creating Multi-project Builds ”. I hope this review also demonstrated that Gradle’s documentation is written at 5+ and you can easily find what you need if you understand where to look. And this will come when you understand the basics. In addition, Gradle has great tutorials. I would like to finish with a small list of what else you can see using Gradle:
A quick introduction to Gradle - 10
#Viacheslav
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION