114

What would be the easiest way to tell Gradle the following:

Retrieve 'junit' dependency and take its latest 'release' version.

Managing Maven and Ivy repositories is sort of new to me. I tried the following steps and they result in Could not resolve dependency ... error:

  • Write compile "junit:junit:latest.release" with repositories set to only mavenCentral() (however, it works if I say "junit:junit:4.10").

  • Write compile "junit:junit:latest.release" with repository set the following way:

    ivy {
        // I also tried 'http://maven.org' and other possible variants.           
        url "http://repo1.maven.org" 
        layout "maven"
    }
    
  • Attempted to use Spring Source Ivy repository:

    ivy {
        artifactPattern "http://repository.springsource.com/ivy/libraries/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
        ivyPattern "http://repository.springsource.com/ivy/libraries/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
    }
    

Maybe I misunderstand something. Why would getting the latest version of the dependency be such a hard task?

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Yippie-Ki-Yay
  • 22,026
  • 26
  • 90
  • 148
  • Dynamic version can be a placeholder for the latest version available, `latest.integration`. [gradle documentation for dynamic versions](https://docs.gradle.org/current/userguide/dependency_management.html#sub:dynamic_versions_and_changing_modules) – Bhavik Oct 28 '16 at 19:35

6 Answers6

287

It can be quite useful sometimes to get the latest release - if for example you release often your own dependencies.

You can get the latest version like

compile "junit:junit:+"

or better specify at least the major version like

compile "junit:junit:4.+"
jmruc
  • 5,714
  • 3
  • 22
  • 41
  • 37
    just for the record: that should indeed be double-quotes! I've been using single-quotes for most of my dependency declarations and found out that `code 'junit:junit:4.+'` doesn't work – azonli Feb 20 '13 at 11:32
  • 1
    @azonli Seems to work for me with single quotes, at least for local dependencies. What error do you get? – David Moles Apr 21 '14 at 18:11
  • 3
    shouldn't it be "testCompile" instead of "compile"? because artifact is not needed in a release – Martin Dürrmeier Dec 15 '15 at 16:23
  • 1
    This approach will not make builds reproducible, I think [Ben Marten's answer](http://stackoverflow.com/a/29492062/1310566) is a better approach. – Simon Forsberg Apr 22 '16 at 13:02
  • 6
    You doesn't always need a reproducible build. – Lakatos Gyula Sep 22 '16 at 15:20
  • 2
    @SimonForsberg ... True, however when you are under-development you may want to (a) follow the _bleeding-edge_ or (b) ensure bug-fixes for v`4.+` are kept up to date for your project. _When_ you reach Alpha, Beta, -RC or -RELEASE stage; I totally agree you need to '_nail_' those versions to a pole. I use a `properties' file to set version specifiers: `compile "junit:junit:${**junitVer**}"`. – will Oct 05 '16 at 13:42
  • Caution: the last version include the alpha and beta versions, by example for `com.android.tools.build:gradle` from google repository. – e-info128 May 26 '20 at 03:45
  • 1
    Important hint: the + does not necessarily take the _latest_ version. It just takes _any_ version satisfying the requested version string in any way. Means: if Gradle has already something in its cache (say 4.1), it won't download a newer version (say 4.21)! To really use the latest version you need to call Gradle with --refresh-dependencies additionally to the + – Harry G. Jun 19 '20 at 15:23
61

Gradle currently does not support Maven's RELEASE (which is rarely used and deprecated) but it does support Ivy's latest.release (and for snapshots latest.integration). However, the general recommendation is to build against exact versions. Otherwise, the build can become a lottery.

bric3
  • 40,072
  • 9
  • 91
  • 111
Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
  • Maven doesn't support RELEASE as well. Only fixed version numbers. – khmarbaise Apr 29 '12 at 12:36
  • 11
    I've double checked. Maven does support `RELEASE`, both in version 2 and 3. – Peter Niederwieser Apr 29 '12 at 13:44
  • 1
    You are right. I've mistaken that with the plugin versions, cause for Maven 3 it does not allow RELEASE/LATEST anymore. But it's of course bad practice to use such version identifiers. – khmarbaise Apr 29 '12 at 14:26
  • An artifact in a Maven Release repository is one that has completed all possible automated (and perhaps manual) testing. That process should include API compatibility checks, regression testing and so on. Why then can the build become a lottery? Only if you are "releasing" artifacts that have not been sufficiently tested. – RCross Oct 24 '14 at 13:52
  • If you don't know what you are building against, you can't reason about compatibility anymore (especially if it's not just the patch level you don't know about), and have also lost the ability to reproduce the build later on. Anyway, by now Gradle supports `latest.release` (both for Ivy and Maven repos) and, if I'm not mistaken, even `RELEASE`. – Peter Niederwieser Oct 24 '14 at 16:32
  • 3
    Grade supports 'latest.release' (but not 'RELEASE'). This is extremely useful for ensuring that your own internal libraries are at the most recent, proven version - I would of course never advocate its use for external/3rd-party libraries for the same reason Peter suggests above. – RCross Aug 14 '15 at 15:54
  • It doesn't seem to work for snapshots though. Ahh it's `latest.integration` ! – bric3 Mar 21 '22 at 09:19
26

Check out the Gradle-Versions-Plugin. It does exactly what you want: https://github.com/ben-manes/gradle-versions-plugin

For the installation, see the github page. Basically you need to add these two lines to your build.gradle - project file:

apply plugin: 'com.github.ben-manes.versions'

buildscript {
    [...]
    dependencies {
        classpath 'com.github.ben-manes:gradle-versions-plugin:0.8'
        [...]
    }
}
[...]

Then you can use the plugin, by running this command in terminal in your project dir:

./gradlew dependencyUpdates -Drevision=release

And it will show you which dependencies are outdated!

electronix384128
  • 6,625
  • 11
  • 45
  • 67
  • You can also add this to an initscript if you don't want to have to include the plugin in every one of your projects. See [this answer to another question](https://stackoverflow.com/a/48341661/90848) for details. – Laurence Gonsalves Mar 22 '18 at 19:17
  • what if the dependencies are in the same repo, and you always want the latest version? – Barry Kelly Feb 03 '20 at 12:02
10

Latest Gradle User Guide mentions and explains plus sign in versions:

From 7.2. Declaring your dependencies:

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

... The build script also states that any junit >= 4.0 is required to compile the project's tests.

From 23.7. How dependency resolution works:

If the dependency is declared as a dynamic version (like 1.+), Gradle will resolve this to the newest available static version (like 1.2) in the repository. For Maven repositories, this is done using the maven-metadata.xml file, while for Ivy repositories this is done by directory listing.

RunninglVlan
  • 170
  • 2
  • 13
3

In Android Studio:

If you're using + for the version, and want to know which version is actually being used, select Project in the sidebar, and then under External Libraries you will see the actual version number in use.

lenooh
  • 10,364
  • 5
  • 58
  • 49
0

Another similar notation for Kotlin DSL (build.gradle.kts):

dependencies {
    implementation("or.jsoup", "jsoup") {
        version {
            require("1.14.+")
        }
    }
    // OR simply
    // implementation("or.jsoup:jsoup:1.14.+")
}

Read more about this in Gradle documentations.

An excerpt from the docs:

A dynamic version can be either a version range (e.g. 2.+) or it can be a placeholder for the latest version available e.g. latest.integration.

Mahozad
  • 18,032
  • 13
  • 118
  • 133