Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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 = "build@master.org"

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?

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.

Hi,peter.Do you which grammar does ext involved in groovy?Or it is only in grade grammar?@Peter Niederwieser – wanglugao Mar 15, 2017 at 13:29 I would be great if some one can point me where can I find documentation on the use of "ext block", tks. – GreenLake4964 Mar 15, 2021 at 6:23

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 = "build@master.org"

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:

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

  • 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 = "build@master.org"
    Hope this helps. Groovy closures get some time getting used to...

    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 = "build@master.org"
    println "myExtInstance.springVersion" + myExtInstance.springVersion
    

    See ExtraPropertiesExtension docs

    You don't need the myExt method in this example, like ext is the instance of the ExtraPropertiesExtension too. – kb1000 Jan 20, 2019 at 7:31

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.