'Gradle - get URL of dependency artifact

I want to download the dependency artifacts manually in the future after Gradle has all the dependency artifacts available, hence I would like to get the URLs which Gradle used to download those artifacts.

Is there a way to get the URL of dependencies which artifacts have been downloaded by Gradle?



Solution 1:[1]

use gson for a example:

dependencies {
    // https://mvnrepository.com/artifact/com.google.code.gson/gson
    compile 'com.google.code.gson:gson:2.8.6'
}

create a task to print url:

task getURLofDependencyArtifact() {
    doFirst {
        project.configurations.compile.dependencies.each { dependency ->
            for (ArtifactRepository repository : project.repositories.asList()) {
                def url = repository.properties.get('url')
                //https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar
                def jarUrl = String.format("%s%s/%s/%s/%s-%s.jar", url.toString(),
                        dependency.group.replace('.', '/'), dependency.name, dependency.version,
                        dependency.name, dependency.version)
                try {
                    def jarfile = new URL(jarUrl)
                    def inStream = jarfile.openStream();
                    if (inStream != null) {
                        println(String.format("%s:%s:%s", dependency.group, dependency.name, dependency.version)
                                + " -> " + jarUrl)
                        return
                    }
                } catch (Exception ignored) {
                }
            }
        }
    }
}

run ./gradlew getURLofDependencyArtifact

Task :getURLofDependencyArtifact

com.google.code.gson:gson:2.8.6 -> https://jcenter.bintray.com/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar

PS:the result dependency your project's

repositories {
    jcenter()
    mavenCentral()
}

so, the result maybe:

Task :getURLofDependencyArtifact

com.google.code.gson:gson:2.8.6 -> https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar

Solution 2:[2]

using Gradle version 6.0 or above, another way of outputting the URLs is to mix --refresh-dependencies with --info

// bash/terminal
./gradlew --info --refresh-dependencies
// cmd
gradlew --info --refresh-dependencies

or output to file

// bash/terminal
./gradlew --info --refresh-dependencies > urls.txt
// cmd
gradlew --info --refresh-dependencies > urls.txt

note on --refresh-dependencies

It’s a common misconception to think that using --refresh-dependencies will force download of dependencies. This is not the case: Gradle will only perform what is strictly required to refresh the dynamic dependencies. This may involve downloading new listing or metadata files, or even artifacts, but if nothing changed, the impact is minimal.

source: https://docs.gradle.org/current/userguide/dependency_management.html

see also: How can I force gradle to redownload dependencies?

Solution 3:[3]

Wanted something similar but on Android and Kotlin DSL so based on @andforce's answer developed this which hopefully will be useful for others also,

import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import java.net.URL

val dependenciesURLs: Sequence<Pair<String, URL?>>
    get() = project.configurations.getByName(
        "implementation"
    ).dependencies.asSequence().mapNotNull {
        it.run { "$group:$name:$version" } to project.repositories.mapNotNull { repo ->
            (repo as? UrlArtifactRepository)?.url
        }.flatMap { repoUrl ->
            "%s/%s/%s/%s/%s-%s".format(
                repoUrl.toString().trimEnd('/'),
                it.group?.replace('.', '/') ?: "", it.name, it.version,
                it.name, it.version
            ).let { x -> listOf("$x.jar", "$x.aar") }
        }.firstNotNullResult { url ->
            runCatching {
                val connection = URL(url).openConnection()
                connection.getInputStream() ?: throw Exception()
                connection.url
            }.getOrNull()
        }
    }
tasks.register("printDependenciesURLs") {
    doLast {
        dependenciesURLs.forEach { (dependency: String, url: URL?) -> println("$dependency => $url") }
    }
}

Update: It might not able to find indirect dependencies however.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 andforce
Solution 2 MikeM
Solution 3 Edric