String interpolation fails in dependencies with ${ext['jackson.version']}


(Sébastien Deleuze) #1

While in Gradle we usually tend to use variable like jacksonVersion, in Spring Boot application we tend to use jackson.version to override the default version. This kind of variable name is defined via ext['jackson.version'] = '2.7.3' for example.

Since we can’t write compile("foo:bar:${jackson.version}") because of the dot, I tried compile("foo:bar:${ext['jackson.version']}") but while String interpolation works if I write println "${ext['jackson.version']}", if I try to write dependencies { compile("foo:bar:${jackson.version}") } it fails with the following error: Error:(55, 0) Cannot get property 'jackson.version' on extra properties extension as it does not exist.

To make it easier to reproduce, String interpolation fails at dependency level:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE'
    }
}

apply plugin: 'spring-boot'

repositories {
    jcenter()
}

ext['jackson.version'] = '2.7.3'
println ext['jackson.version']
println "${ext['jackson.version']}"

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile "com.fasterxml.jackson.module:jackson-module-kotlin:${ext['jackson.version']}"
}

While it works at dependencyManagement level:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE'
    }
}

apply plugin: 'spring-boot'

repositories {
    jcenter()
}

ext['jackson.version'] = '2.7.3'

dependencyManagement {
    dependencies {
        dependency "com.fasterxml.jackson.module:jackson-module-kotlin:${ext['jackson.version']}"
    }
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'com.fasterxml.jackson.module:jackson-module-kotlin'
}

Could it be possible to make it works at dependency level like in other places?


(Eric Wendelin) #2

To get it working at the dependency level you need ${project.ext['jackson.version']}

When you’re writing ext['foo'] = 'bar' in your build script, you’re setting a extra property on the Project object.

My guess is that the dependencyManagement plugin delegates to the project object when it can’t find ext which allows this to work. The dependencies {} block does not.


(Sébastien Deleuze) #3

Thanks for the workaround.

Could it be possible to create an enhancement request on https://issues.gradle.org in order to ask support for ${ext['jackson.version']} in dependencies block (like it is currently supported in dependencyManagement)?


(Stefan Oehme) #4

That is very unlikely to happen, because your code specifically asked for the ext property of the dependencies handler. The fact that spring-boot’s dependencyManagement handler does not have an ext properties container should not drive the design of Gradle core.

You can work around this and make your code more readable by using this pattern:

ext.versions = [
   jackson: '2.7.3'
  //more versions here
]

dependencies {
  compile "com.fasterxml.jackson.module:jackson-module-kotlin:${versions.jackson}"
}