2021-10-03

2: Trying to Make Sense of Gradle Scripts as Groovy Code

<The previous article in this series | The table of contents of this series | The next article in this series>

Gradle scripts are based on Groovy (forget about Kotlin here), but are not exactly Groovy code. Here is an outline of what Gradle is doing secretly.

Topics


About: Gradle
About: Groovy

The table of contents of this article


Starting Context


  • The reader has a basic knowledge on Groovy or Java.

Target Context


  • The reader will know how Groovy Gradle scripts are not really Groovy scripts and an outline of what Gradle is doing secretly..

Orientation


Here is the 1st step toward beginning to fully exploit Gradle.


Main Body

Stage Direction
Here is Special-Student-7 in a room in an old rather isolated house surrounded by some mountains in Japan.


1: We Have Rectified That Unreasonable "Hello World" Script to Be More Reasonable as Groovy Code, but Still It Does Not Make Sense . . .


Special-Student-7-Hypothesizer
We have rectified that unreasonable "Hello World" script to be more reasonable in the previous article.

@Gradle Source Code
task ("hello", {
	doLast ({
		println ('Hello world!')
	})
})

But, still, it does not make sense . . .

'task' is a function and seems to be a method of the 'org.gradle.api.Project' interface (in fact, implemented by 'org.gradle.api.internal.project.DefaultProject', etc.), apparently.

However, how is that unqualified 'task' call in the script delivered to the project instance? Does the script really run inside the project class? . . . No, it runs inside a 'groovy.lang.Script' sub class.

What is going on there? Well, I need to learn some basics of Groovy in order to understand that.


2: Some Basics of Groovy


Special-Student-7-Hypothesizer
In the 1st place, how does any Groovy script become to be executed?

Groovy is based on Java, right? As I understand that Java does not let any logic sit outside any class, is the script incorporated into a Java class, I guess?

. . . Yes, it is; more precisely, it is incorporated into an automatically-generated 'groovy.lang.Script' sub class as described in the official document of Groovy.

Although the main logic goes into the 'run' method of the 'groovy.lang.Script' sub class, it is not as simple as that the whole script code just goes into the 'run' method. That is because some statements like 'import' directives and function definitions cannot go inside any method, Java-wise.

An important fact to be aware of is that Groovy method calls do not become simple Java method calls, which is the reason why the "dynamic method" functionality is possible in Groovy. . . . So, Groovy has indeed a mechanism that allows non-existent methods to be called or non-existent properties to be accessed.

Special-Student-7-Rebutter
Well, the official Groovy document looks to be fairly well-written, compared with, for example, Gradle's; it is understandable.


3: The Reality of Gradle Scripts


Special-Student-7-Hypothesizer
However, in order for the mechanism to be put in effect, of course, some arrangements are required to have been made, which I do not see inside the Gradle script. Namely, a 'methodMissing' method has to be in place.

The fact is that the Gradle script is not passed into Groovy even after it has been preprocessed.

In fact, the Gradle script is incorporated into an automatically-generated 'org.gradle.groovy.scripts.BasicScript' sub class (note that 'org.gradle.groovy.scripts.BasicScript' is a Gradle class).

Special-Student-7-Rebutter
So, the Gradle script is not really a Groovy script . . .

Special-Student-7-Hypothesizer
I can guess now that 'org.gradle.groovy.scripts.BasicScript' is in charge of delivering undefined-in-the-script-class property or method calls to the project instance.

I will not dig into how exactly 'org.gradle.groovy.scripts.BasicScript' does so, but I need to know that the Gradle script becomes a 'org.gradle.groovy.scripts.BasicScript' sub class, which is a sub class of the Groovy-standard 'groovy.lang.Script' class, and the sub class delivers undefined-in-it property or method calls to the project instance.

That level of clarification is due to users, in my opinion.

Special-Student-7-Rebutter
I agree. As the Gradle official document does not make that point clear, its discourse does not make sense; it is not understandable, really.

Special-Student-7-Hypothesizer
What I sense in the Gradle official document is a disgustingly patronizing attitude to say "You don't need to understand.". I need to understand!


References


<The previous article in this series | The table of contents of this series | The next article in this series>