ext and code block's meaning in the gradle file

GroovyGradle

Groovy Problem Overview


ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

Above code is the snippet of build.gradle

I understand that call ext method with { } closure parameter. it's right? So I think gradle is accessing springVersion and emailNotification. I'm gonna verify my assumption with below code

def ext(data) {
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

but run that code below Error occured.

groovy.lang.MissingPropertyException: No such property: springVersion for class: Test

do you explain ext and code block specifically?

Groovy Solutions


Solution 1 - Groovy

ext is shorthand for project.ext, and is used to define extra properties for the project object. (It's also possible to define extra properties for many other objects.) When reading an extra property, the ext. is omitted (e.g. println project.springVersion or println springVersion). The same works from within methods. It does not make sense to declare a method named ext.

Solution 2 - Groovy

Here is the explanation for why the sample code in the question produces an error.

In the code:

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

Does not pass to the function "ext" an object that has the springVersion and emailNotification properties. The curly braces don't mean a POJO but a closure. This is why the "ext" function complains it can't get to the properties.

The idea with passing such a closure, known as a configuration closure, is that the receiving function will:

  1. Modify the delegate property of the closure to point to an object that the closure properties/methods should act on.

  2. execute the closure()

Thus the closure executes and when it refers to methods / properties these will be executed on the object to be configured.

Thus, the following modification to your code will make it work:

class DataObject {
   String springVersion;
   String emailNotification;
}

def ext(closure) {  
    def data = new DataObject() // This is the object to configure.
    closure.delegate = data;
    // need this resolve strategy for properties or they just get
    // created in the closure instead of being delegated to the object
    // to be configured. For methods you don't need this as the default
    // strategy is usually fine.
    closure.resolveStrategy = Closure.DELEGATE_FIRST 
    closure() // execute the configuration closure
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

ā€‹ Hope this helps. Groovy closures get some time getting used to...

Solution 3 - Groovy

It's the overriding of get() and set() by ExtraPropertiesExtension that is the key to making the configuration syntax for never before defined properties work.

class DataObject {
    HashMap<String, Object> props = new HashMap<String, Object>()

    Object get(String name) {
        return props.get(name)
    }

    void set(String name, @Nullable Object value) {
        props.put(name, value)
    }
}

def myExtInstance = new DataObject()

def myExt = { Closure closure ->
    def data = myExtInstance
    closure.delegate = data;
    // need this resolve strategy for properties or they just get
    // created in the closure instead of being delegated to the object
    // to be configured. For methods you don't need this as the default
    // strategy is usually fine.
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure() // execute the configuration closure
    println data.springVersion
}

myExt {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "[email protected]"
}

println "myExtInstance.springVersion" + myExtInstance.springVersion

See ExtraPropertiesExtension docs

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionuuidcodeView Question on Stackoverflow
Solution 1 - GroovyPeter NiederwieserView Answer on Stackoverflow
Solution 2 - GroovyRonenView Answer on Stackoverflow
Solution 3 - Groovyenl8enmentnowView Answer on Stackoverflow