How do I define a variable for the dependency version in Gradle
Asked Answered
B

11

89

I am currently trying to migrate a Maven project to Gradle

In my Maven version I have the dependency versions all listed out like this in my parent pom:

<properties>
    <spring.version>4.2.3.RELEASE</spring.version>
    <spring.boot.version>1.3.3.RELEASE</spring.boot.version>
    ...
</properties>

And then I can define a dependency like this in any of my sub-modules:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>

I am attempting to do the same thing on Gradle, because some of my modules share dependency versions like this, and I wouldn't like to modify more then one place if I want to upgrade Spring or do a similar operation.

The closest I have gotten to it is this:

dependencies {
    ext.springVersion = '4.2.3.RELEASE'
    compile "org.springframework:spring-jdbc:$springVersion"
}

Yet that still doesn't work. What is the recommended way to achieve this in Gradle? Or does Gradle treat this differently? Perhaps my mind is still too much on Maven to see another solution.

Please keep in mind that that attempt on Gradle isn't exactly what I want yet. I would like to be able to define the dependencies in a separate file, not directly on the file that will use it.

Brachycephalic answered 29/6, 2016 at 17:38 Comment(2)
I've seen examples with that "ext." assignment before the dependencies block. When you say "that still doesn't work", what exactly happens?Brandiebrandise
The IDE points out errors saying that the variable was not found and does not import the library... But then again, maybe this is more related to IntelliJ IDEA then gradle itselfBrachycephalic
M
14

The way you've provided dependency version is correct and should work. IntelliJ Idea has some troubles with variables within gradle build scripts, so you don't have to rely on it, just try to run your build and check out, whether is dependency downloaded and your project is build correctly.

If you wish to store your project dependencies in the separate file, then the most common approach is to define them in the root build.script, via subprojects closure for all subprojects or via allprojects if you wish to specify dependency for all your projects include the root. This will look like this:

subprojects{
    dependencies{
        compile ...
    }
}

This way you can provide any common configuration for subprojects within the root build script. Read about it the user guide

Or you can declare a variable in the root build script, initialize it as an map with all the dependency specifications you need or as an array with single dependencies list and use this variable within your subprojects, if you need them. Somethin like this in the root:

ext.commomLibs = [
  'testlibs' : 'junit:junit:4.8'
]

Note, you can define a value of the map as an array of the lib specification to make it pointing to all this dependencies. And then you can use it in your subprojects as:

dependencies{
    testCompile commomLibs.testlibs
}

One more alternative is to use separate build script with dependencies and apply it to the buils script you need, like so

apply from: 'dependencies.script'

Then you can place your dependencies into dependencies script and just apply it in any other build script, where you need this dependenies and/or may be some common logic.

Muzzy answered 29/6, 2016 at 19:37 Comment(2)
Can you give instructions for the alternative method using apply from:?Casias
Can you please give the equivalent for Gradle 7.1.1 ? Since none of the answers in this thread seem working for that version of gradle build.Microphone
P
87

Below configuration in build.gradle file worked for me with gradle version 4.5, posting it here for future reference -

ext {
    springVersion = '5.0.3.RELEASE'
}

dependencies {
    compile  "org.springframework:spring-context:$springVersion"
}
Popp answered 2/2, 2018 at 7:20 Comment(2)
note that single quotes in <compile> don't work, should be double.Absently
After replacing compile with implementation, I can confirm it's working with gradle version 5.6 and with gradle version 6.2Proprioceptor
C
37

Use Double Quotes it worked for me.

buildscript {
    ext {
        springBootVersion = '2.0.4.RELEASE'
        hazelCastVersion = '3.10.4'
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")

    }
}

dependencies {
    compile('org.springframework.cloud:spring-cloud-starter-config')
    compile "com.hazelcast:hazelcast-spring:${hazelCastVersion}"
    compile group: 'com.hazelcast', name: 'hazelcast', version: "${hazelCastVersion}" }
Corporate answered 19/8, 2018 at 20:22 Comment(2)
Thanks for including the "compile group" syntax sugar in this answer.Mayramays
What's the difference between ext and buildscript.ext?Eddings
M
14

The way you've provided dependency version is correct and should work. IntelliJ Idea has some troubles with variables within gradle build scripts, so you don't have to rely on it, just try to run your build and check out, whether is dependency downloaded and your project is build correctly.

If you wish to store your project dependencies in the separate file, then the most common approach is to define them in the root build.script, via subprojects closure for all subprojects or via allprojects if you wish to specify dependency for all your projects include the root. This will look like this:

subprojects{
    dependencies{
        compile ...
    }
}

This way you can provide any common configuration for subprojects within the root build script. Read about it the user guide

Or you can declare a variable in the root build script, initialize it as an map with all the dependency specifications you need or as an array with single dependencies list and use this variable within your subprojects, if you need them. Somethin like this in the root:

ext.commomLibs = [
  'testlibs' : 'junit:junit:4.8'
]

Note, you can define a value of the map as an array of the lib specification to make it pointing to all this dependencies. And then you can use it in your subprojects as:

dependencies{
    testCompile commomLibs.testlibs
}

One more alternative is to use separate build script with dependencies and apply it to the buils script you need, like so

apply from: 'dependencies.script'

Then you can place your dependencies into dependencies script and just apply it in any other build script, where you need this dependenies and/or may be some common logic.

Muzzy answered 29/6, 2016 at 19:37 Comment(2)
Can you give instructions for the alternative method using apply from:?Casias
Can you please give the equivalent for Gradle 7.1.1 ? Since none of the answers in this thread seem working for that version of gradle build.Microphone
H
11

You can use now even more close to the dependencies in the App Gradle Build as shown below:

dependencies {
    def daggerVersion = "2.24"
    implementation "com.google.dagger:dagger:$daggerVersion"
    annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
}
Hite answered 10/10, 2019 at 14:51 Comment(0)
S
4

Adding to Vikas Sachdeva's answer:

It's not worked for me in that way on my subproject. The Gradle throws an error 'Could not find org.springframework:spring-context:$springVersion'. Finally, I solved my problem by adding the plus sign.

for example:

root gradle.properties:

springVersion = '5.0.3.RELEASE'

root build.gradle

dependencies {
    compile  "org.springframework:spring-context:${springVersion}"
}

subproject build.gradle

dependencies {
    compile  "org.springframework:spring-context:" + springVersion
}

Note: my gradle version is 5.4.1

or you can using the plugin manage your dependency version.

io.spring.dependency-management

Refs: https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/

Selfsustaining answered 13/5, 2019 at 6:55 Comment(1)
Likely in your subproject, you had single quotes, not double quotes. Groovy/Gradle makes a difference between "${foo}" and '${foo}'. Only the first will substitute. Also note gradle.properties is not ideal to contain dependency versions. The normal way is to use extra properties like "ext { ... }" In your build.gradle file.Korea
D
3

On gradle v6.1.1, the simplest is:

dependencies {
    def jerseyVersion = '2.29.1'
    compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: jerseyVersion

    // ...
}
Deficit answered 9/4, 2020 at 12:21 Comment(0)
H
3

Modern way to manage dependencies in gradle described in this article: https://docs.gradle.org/current/userguide/platforms.html#sub:central-declaration-of-dependencies

Personally, I prefer .toml file: https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml It is clear, type-safe and IDEA linter works well with it.

Higgler answered 18/2, 2022 at 9:50 Comment(1)
A link to a solution is welcome, but please ensure your answer is useful without it: add context around the link so your fellow users will have some idea what it is and why it is there, then quote the most relevant part of the page you are linking to in case the target page is unavailable. Answers that are little more than a link may be deleted.Oxen
H
1

Another way to do that: Create a file in the same directory of your build.gradle app. Name this new file like this: dependencies.gradle In your build.gradle app add this line on top

apply from: 'dependencies.gradle'

define your variables in the dependencies.gradle like this:

ext {

versions = [
    camerax_version : "1.1.0-alpha10",
    camerax_extra_version : "1.0.0-alpha24",
    constraintlayout : "2.0.3",
    appcompat : "1.2.0"
]

camerax = [
        camerax_core : "androidx.camera:camera-core:${versions.camerax_version}",
        camerax_camera2 : "androidx.camera:camera-camera2:${versions.camerax_version}",
        camerax_lifecycle : "androidx.camera:camera-lifecycle:${versions.camerax_version}",
        camerax_extensions : "androidx.camera:camera-extensions:${versions.camerax_extra_version}",
        camerax_view : "androidx.camera:camera-view:${versions.camerax_extra_version}"
]

androidx = [
        constraints_layout : "androidx.constraintlayout:constraintlayout:${versions.constraintlayout}",
        appcompat : 'androidx.appcompat:appcompat:${versions.appcompat}'
]}

Finally use these variables in your build.gradle module like this

implementation camerax.camerax_core
implementation camerax.camerax_camera2
implementation camerax.camerax_lifecycle
implementation camerax.camerax_extensions
implementation camerax.camerax_view
Horsa answered 3/11, 2021 at 14:13 Comment(0)
B
1

The best practice for declaring dependency versions as variables in Gradle

For Android projects that include multiple modules,

it may be useful to define certain properties at the project level and share them across all the modules. You can do this by adding extra properties to the ext block in the top-level build.gradle file, like this.

Inside buildscript block add your version variables in ext block

ext {
    version_navigation = "2.5.1"
    version_lifecycle = "2.5.1"
    version_kotlin = "1.7.10"
}

For a single-module project (app module only) use app's build.gradle

In the root add your version variables inside ext block

ext {
    version_navigation = "2.5.1"
    version_lifecycle = "2.5.1"
    version_kotlin = "1.7.10"
}
Berar answered 7/8, 2022 at 18:59 Comment(0)
M
0

I have a an alternate syntax sugar. I guess this is the "long" way of writing the dependency.

master "gradle.build"

plugins {
    id 'java'
}


ext {
    slf4jApiVersion = '1.7.28'
    junitVersion = '4.12'
}

sub module / project gradle.build

dependencies {
    testCompile group: 'junit', name: 'junit', version: "${junitVersion}"
    compile group: 'org.slf4j', name: 'slf4j-api', version: "${slf4jApiVersion}"
}

note the seperation of group, name and version... SINQLE quotes around group and name values, and DOUBLE quotes around the version-value-variable.

Mayramays answered 19/8, 2019 at 22:6 Comment(0)
F
0

In simple terms you can use a place holder and provide the value in the extension block.

e.g.

ext {
    lombokVersion = '1.18.26'
}

and now use the placeholder in defining dependency

compileOnly "org.projectlombok:lombok:${lombokVersion}"

We can also provide a dynamic value of this placeholder if required.

./gradlew clean build -PlombokVersion=1.18.30

and now below code will print 1.18.30

ext {
    println('lombokVersion found '+lombokVersion);
    //lombokVersion = '1.18.26'
}

Given, gradle is based on groovy, the above code can be modified to override the static version from the one provided dynamically based on the availability.

Finitude answered 29/4 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.