18

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?

Hans
  • 400
  • 2
  • 11
  • 3
    The two forum pages suggest that this is not possible yet. https://discuss.gradle.org/t/how-do-you-find-the-source-url-for-a-dependency/13885 https://discuss.gradle.org/t/how-to-get-urls-for-dependencies/6349/2 – Hans Jun 09 '16 at 09:47

4 Answers4

8

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

andforce
  • 147
  • 1
  • 6
  • `dependency.group.replace` may fail if the group is null, so the `try` should be moved up before the `def jarUrl` line, IMO. – Robin Green Dec 14 '20 at 16:59
  • I am getting dependencies with URL as `.m2` local folder. Is there a way to get artifact URL instead of `.m2` location? – Ayman Patel Feb 05 '21 at 04:52
  • @AymanPatel Just filter out the mavenLocal repository from project.repositories. – TobTobXX Jun 01 '22 at 15:52
6

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?

MikeM
  • 27,227
  • 4
  • 64
  • 80
1

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.

Edric
  • 24,639
  • 13
  • 81
  • 91
Ebrahim Byagowi
  • 10,338
  • 4
  • 70
  • 81
0

We need to take care about aar also.

 project.configurations.getByName(
                "implementation"
        ).dependencies.each { dependency ->
           
            for (ArtifactRepository repository : rootProject.repositories.asList()) {
                def url = repository.properties.get('url')
                def urlString = url.toString()
                if (url.toString().endsWith("/")) {
                    urlString = url.toString()
                } else {
                    urlString = url.toString() + "/"
                }
                def jarUrl = String.format("%s%s/%s/%s/%s-%s.jar", urlString,
                        dependency.group.replace('.', '/'), dependency.name, dependency.version,
                        dependency.name, dependency.version)

                def aarUrl = String.format("%s%s/%s/%s/%s-%s.aar", urlString,
                        dependency.group.replace('.', '/'), dependency.name, dependency.version,
                        dependency.name, dependency.version)
                try {
                    def jarfile = new URL(jarUrl)
                    def inStreamJar = jarfile.openStream();
                    if (inStreamJar != null) {
                        println(String.format("%s:%s:%s", dependency.group, dependency.name, dependency.version)
                                + " -> " + jarUrl)
                        return
                    }
                } catch (Exception ignored) {
                }

                try {
                    def aarfile = new URL(aarUrl).setURLStreamHandlerFactory()
                    def inStreamAar = aarfile.openStream();
                    if (inStreamAar != null) {
                        println(String.format("%s:%s:%s", dependency.group, dependency.name, dependency.version)
                                + " -> " + aarUrl)
                        return
                    }
                } catch (Exception ignored) {
                }
            }
        }

vipuld
  • 1
  • 1